
📕 READ ME
🚧 UNPUBLISHED AND ONGOING example 🚧 The data in
this script are currently unpublished, and the
analysis is ongoing. Some sections may be incomplete.
This script has been made publicly available to facilitate sharing with
collaborators and colleagues who are interested in the progress of the
project and to ensure transparency.
SUMMARY This R code estimates the relationship
between oxygen consumption (MO₂) and dissolved oxygen saturation (DO) in
the Common Galaxias (Galaxias maculatus). It also estimates the
critical oxygen saturation value for aerobic metabolism
O2crit, commonly defined as the threshold below which the
oxygen consumption rate can no longer be sustained. The associated
article is titled “The role of osmorespiratory compromise in hypoxia
tolerance of the purportedly oxyconforming teleost Galaxias
maculatus.” If you are reading the HTML version of this script,
click the Code button in the top right to download the
.Rmd file.
AIM The article aims to test whether Galaxias
maculatus can maintain oxygen consumption (MO₂) as ambient DO
declines and, if so, at what level it reaches the critical oxygen
saturation value for aerobic metabolism (O2crit).
AUTHORS Timothy D. Clark [a] Maryane
Gradito [a] Elizabeth C. Hoots [a] Luis L.
Kuchenmüller [a] Jake M. Martin [a,b]
AFFILIATIONS [a] School of Life and Environmental
Sciences, Deakin University, Geelong, VIC, Australia
[b] Department of Wildlife, Fish and Environmental Studies, Swedish
University of Agricultural Sciences, Umeå, Sweden
CONTRIBUTOR ROLES 🚧 To be
added 🚧 Based on the Contributor Roles Taxonomy
(CRediT)
DISCLAIMER I (Jake Martin) am dyslexic. I have made
an effort to review the script for grammatical errors, but some will
likely remain. I apologise. Please feel free to reach out using the
contact details below if anything is unclear.
📑 Sharing/accessing and citing
Licenses/restrictions placed on the data: CC-BY
4.0
Link to the associated publication:
🚧 To be added 🚧
Recommended citation for this data:
Timothy D. Clark, Maryane Gradito, Elizabeth Hoots, Luis L.
Kuchenmüller, Jake M. Martin (2025). The role of osmorespiratory
compromise in hypoxia tolerance of the purportedly oxyconforming teleost
Galaxias maculatus. OSF DOI:10.17605/OSF.IO/GFXCA (Last Updated: 2025-05-28
12:28 PM)
📦 Required packages and knit settings
A list of the required packages to run the script.
# ----- Packages ------
if (!requireNamespace("pacman", quietly = TRUE)) install.packages("pacman")
# ---- List of required packages ----
pkgs <- c(
# ----- Data Visualisation -----
"ggthemes", "bayesplot", "gt", "gtsummary", "plotly", "qqplotr", "gridExtra",
# ----- Tidy Data and Wrangling -----
"tidyverse", "janitor", "readxl", "broom.mixed", "data.table", "hms", "devtools",
"mclust",
# ----- Modelling and Statistical Analysis -----
"brms", "rstan", "marginaleffects", "performance", "emmeans",
"tidybayes", "respirometry", "future"
)
# ---- Install and load all packages using pacman ----
suppressPackageStartupMessages(
pacman::p_load(char = pkgs, install = TRUE)
)
#-------kniter seetting-----------
knitr::opts_chunk$set(
echo = FALSE, # only for PDF knit
message = FALSE,
warning = FALSE, # no warnings
cache = TRUE,# cacheing to save time when kniting
tidy = TRUE,
fig.align = "center"
)
🔧 Custom functions
Here are some custom functions used within this script.
bayes_incremental_regression_by_id(): A custom function
to build Bayesian incremental regressions. It is designed to run a list
of subgroup models (IDs) in parallel using 4 cores. The function uses
brm() with a Gaussian error distribution.
Use:
The function accepts the following arguments:
- id_i: A grouping factor or ID used to filter the data for
each regression. If none is provided, the function uses the entire
dataset.
- id_name: The column name (as a character string)
corresponding to the grouping factor in the data frame. If not provided,
the function uses all data.
- data: The data frame containing the variables for
analysis.
- predictor: The predictor variable of interest.
- response: The response variable of interest.
- seed_number: A random seed value for model
reproducibility.
- save_models: A logical argument indicating whether to
save the model outputs (TRUE or FALSE).
- mod_output_wd: The output directory where model
.rds files should be saved (used only if
save_models = TRUE).
load_rds9(): A custom function to load all rds models in
a directory and store in a list. Takes a directory with
.rds files
incremental_regression_bayes_fits(): A custom function
for pulling model fits, loo and r2 using loo() and
bayes_R2(), respectively. Takes a list of brm
models.
bayes_mod_predictions(): This function extracts the
predicted values using fitted() from a list of models and
combines them with the original data file used for the model. These are
the posterior mean fitted values (i.e. the expected
value of the response variable given the predictor variables and the
estimated posterior distributions of the parameters) for each
observation in the dataset, along with 95% credible
intervals.
calcSMR(): authored by Denis Chabot
used to estimate SMR with several different methods Claireaux and Chabot
(2016) [1]
[1] Claireaux, G. and Chabot, D. (2016) Responses by
fishes to environmental hypoxia: integration through Fry’s concept of
aerobic metabolic scope. Journal of Fish Biology https://doi.org/10.1111/jfb.12833
calcO2crit(): authored by Denis Chabot
used to estimate O2crit (Pcript). Claireaux and Chabot (2016)
[1]
Note: O2 is assumed to be in percentage of dissolved
oxygen (DO)
plotO2crit(): authored by Denis Chabot,
used to plot the modes used for the calcO2crit() function.
Claireaux and Chabot (2016) [1]
Note: I added abline(h=lowestMO2, col=“pink”) so that I
could visualise the lowestMO2 position
📂 Directories
Output
📤 output_fig_wd: this is where we will put the
figures
📤 output_mods_wd: this is where we will put the
models
💿 Data
Slopes (ṀO)
💿 slope_df: We have imported the slopes extracted
in LabChart during each phase of the experiment
Urbina, Glover, and Forster (2012)
💿 urbina_et_al_2012: This is the mean level data
extracted from Urbina, Glover, and Forster (2012)[2] Figure
1a. We used the metaDigitise package in R to extract the data
[3].
O₂crit viusal inspection
💿 o2crit_check: This data frame includes the visual
based assessment for O₂crit for all fish included in the analysis
(n = 58). The inspections were made using figures genbrated by
the plotO2crit() function, and can be viewed in
combined_chabot_plots.pdf. The visual assessment was done
independently by all authors, and the presence of an O₂crits allocated
to ‘yes’, ‘no’, ‘maybe’. If yes, or maybe, an estimate of the dissolved
oxygen percentage was given.
Directory to the figures
📁 gmac-mo2-24/ └── 📂 output-fig/
└── 📂 model_chabot/ └── 📄 combined_chabot_plots.pdf
🧹 Data tidy
Numbers
We have 64 fish with MO₂ data
## [1] "n = 64"
With 48 from the 0 ppt and 48 from 9 ppt groups
| Salinity group |
n total |
| 0 |
33 |
| 9 |
31 |
Fish size
Here we calculate the mean length and size of fish used in the
experiment.
## [1] "The mean mass of fish was 0.532 g (range: 0.21-1.6), and the mean length was 50.41 mm (range: 40-70)"
Filtering trials
We will remove 6 trials which had errors. These are as follows:
- a_0_25nov_3 fish died during trial
- b_0_26nov_4 flat lined early
- c_0_22nov_2 chamber was opened early
- c_9_26nov_2 chamber was opened early
- c_9_26nov_4 chamber was opened early
- d_9_27nov_3 sensor was jumpy and end points were hard to confidently
ID visually
We now have 58 fish with MO2 data
## [1] "n = 58"
With 30 in the 0 ppt group and 28 in the 9 ppt group
| Salinity group |
n total |
| 0 |
30 |
| 9 |
28 |
Mass and size of fish after removing 6 trials which had errors
## [1] "The mean mass of fish was 0.546 g (range: 0.21-1.6), and the mean length was 50.9 mm (range: 40-70)"
Chamber size breakdown
| Chamber type |
n total |
Median mass |
Standard deviation mass |
| 0.058 |
36 |
0.43 |
0.1496554 |
| 0.105 |
21 |
0.61 |
0.2561871 |
| 0.300 |
1 |
1.60 |
0.0000000 |
Numbers per trial approach
| Type of trial |
n total |
| 100c |
19 |
| 50c |
39 |
Filtering MO₂ estimates
Here we apply the following filters to the MO₂ data:
- Remove the first 5 SMR cycles (burn in)
- Remove all positive raw slopes
- Remove all MO₂ calculated using less then 60 data points (5 min at
0.2 Hz)
- Remove all MO₂ calculated if O₂ increases in a closed phase
(i.e. trial has ended)
Check positive values for MO₂ before removing.
## [1] "There are 13 fish with postive slopes. These fish are: a_0_24nov_1, b_0_24nov_3, b_9_21nov_2, b_9_21nov_3, b_9_22nov_1, b_9_22nov_2, b_9_22nov_3, c_0_21nov_1, c_0_21nov_2, c_0_22nov_4, c_9_24nov_3, d_0_22nov_2, d_9_25nov_3. For all estimated slopes (n = 1105) 1.27% were postive (n = 14)"
Filtering the MO₂ data
Calculating SMR
We will calculate SMR using calcSMR function by Chabot,
Steffensen and Farrell (2016)[1]. Specifically, we use mean
of the lowest normal distribution (MLND) where CVmlnd < 5.4 and the
mean of the lower 20% quantile (q0.2) were CVmlnd > 5.4. If CVmlnd is
not calculated we have used q0.2.
Visualising MO2 corrections
Let’s check how data corrections change the appearance of out data
MO2
Let’s compare raw MO2 calculations (mo2), MO2 calculations after
correcting background respiration (mo2_bground), and MO2 calculations
after correcting for background respiration and oxygen diffusion
dynamics (mo2corr). First we will need to make the mo2_bground vaule as
it’s not present in the datafile, and transform the data to long
formate, so we can plot it more easly.
📊 Exploratory Data Analysis (EDA)
Routine MO₂
Making an SMR phase only data frame
Routine MO2 by salinity. Plot of all MO2
measures during SMR phase by salinity treatment. The small points are
the raw observed values, the shaded area behind the points is the a
kernel density of the observed data, the box plot shows the median and
interquartile range (IQR), and the large point shows the mean.

SMR
Here’s the same plot but for only the SMR, as estimated with calcSMR
function by Chabot, Steffensen and Farrell (2016)[1].
Specifically, we use mean of the lowest normal distribution (MLND) where
CVmlnd < 5.4 and the mean of the lower 20% quantile (q0.2) were
CVmlnd > 5.4. If CVmlnd is not calculated we have used q0.2.

Individual O₂, MO₂, and SMR
Here we will plot the individual relationship between O₂, MO₂, and
SMR for all fish
Create output directory if needed
Loop through each fish ID to create a plot, save these to a single
PDF file, this is called combined_slopes.pdf. It can be
found in this path output-fig/slopes/combined_slopes.pdf
These plots show Metabolic rate measurements (MO₂; mg O₂
g-1h-1 by O2) at each of the four
experimental phase (the over night SMR intermittent-flow respirometry
phase, closed phases at 50%, 75% or 100% O2). The estimated
SMR value is represented as a dashed red line.
## png
## 2
🧮 Analysis
Routine MO2
Scaling predictors
Here we scale our predictors for the model. We have first applied an
log transformation to mass, so its directly interpretable as the
mass-scaling exponent, just like in metabolic theory.
Summary of predictors used in the model below
| temp_range |
mass_range |
cycle_range |
number_fish |
| 13.84–14.38 |
0.21–1.6 |
5–27 |
58 |
Model structure
Here we will use a Bayesian Generalised Linear Mixed Model (GLMM)
with a Gamma distribution and a log link, where the shape parameter (α)
is also modelled as a function of predictors. This models MO2
by salinity during the SMR phase to see if the fish held at different
salinities have different RMRs. We have also added a few scaled
predictors, that may help describe variation in the data, such as mass
(g; 0.21–1.6) temperature (°C; 13.84–14.38), cycle order (5–27), and
light/dark cycle (light or dark; light between 07:00:00 and 19:00:00),
we also include a random effect for fish id to account for multiple
MO2 measures on each fish (1–58). We allowed the the shape
parameter (α) to vary as a function of some of the predictors
(e.g. salinity_group, order_z) to improve fit.
Prior selection
These are the default priors. We will use these.
| prior |
class |
coef |
group |
resp |
dpar |
nlpar |
lb |
ub |
source |
|
b |
|
|
|
|
|
|
|
default |
|
b |
light_dark_c |
|
|
|
|
|
|
default |
|
b |
log_mass_c |
|
|
|
|
|
|
default |
|
b |
order_c |
|
|
|
|
|
|
default |
|
b |
salinity_group9 |
|
|
|
|
|
|
default |
|
b |
temp_c |
|
|
|
|
|
|
default |
| student_t(3, -2.7, 2.5) |
Intercept |
|
|
|
|
|
|
|
default |
| student_t(3, 0, 2.5) |
sd |
|
|
|
|
|
0 |
|
default |
|
sd |
|
id |
|
|
|
|
|
default |
|
sd |
Intercept |
id |
|
|
|
|
|
default |
|
b |
|
|
|
shape |
|
|
|
default |
|
b |
order_c |
|
|
shape |
|
|
|
default |
|
b |
salinity_group9 |
|
|
shape |
|
|
|
default |
| student_t(3, 0, 2.5) |
Intercept |
|
|
|
shape |
|
|
|
default |
Run model
Here we run the model, I have hashed this out because I have saved
the model for quick reloading.
⏭️ Skip this step if you have downloaded the saved
model mo2_mod_gamma.rds from GitHub (or pulled the entire
GitHub project)
Here we reload the model
Model diagnostics
Checking model convergence


Checking rhat are equal to one
## Family: gamma
## Links: mu = log; shape = log
## Formula: MO2 ~ temp_c + order_c + light_dark_c + log_mass_c + salinity_group + (1 | id)
## shape ~ salinity_group + order_c
## Data: slope_tidy_smr (Number of observations: 893)
## Draws: 4 chains, each with iter = 8000; warmup = 1000; thin = 2;
## total post-warmup draws = 14000
##
## Multilevel Hyperparameters:
## ~id (Number of levels: 58)
## Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## sd(Intercept) 0.31 0.03 0.26 0.38 1.00 4013 6644
##
## Regression Coefficients:
## Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS
## Intercept -2.54 0.06 -2.66 -2.43 1.00 2241
## shape_Intercept 2.58 0.07 2.45 2.72 1.00 12143
## temp_c -0.33 0.21 -0.75 0.09 1.00 6431
## order_c 0.00 0.00 -0.00 0.01 1.00 11445
## light_dark_c 0.13 0.02 0.09 0.18 1.00 12311
## log_mass_c 0.81 0.10 0.61 1.01 1.00 2943
## salinity_group9 -0.10 0.08 -0.26 0.07 1.00 2304
## shape_salinity_group9 0.18 0.10 -0.03 0.37 1.00 12404
## shape_order_c -0.04 0.01 -0.06 -0.02 1.00 11624
## Tail_ESS
## Intercept 4183
## shape_Intercept 12331
## temp_c 9409
## order_c 12155
## light_dark_c 12266
## log_mass_c 5032
## salinity_group9 4394
## shape_salinity_group9 12389
## shape_order_c 12394
##
## Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
## and Tail_ESS are effective sample size measures, and Rhat is the potential
## scale reduction factor on split chains (at convergence, Rhat = 1).
Using leave one out (loo) measure of fit, the model appears to
preform well, all, but one Pareto k estimates are good (k < 0.7)
##
## Computed from 14000 by 893 log-likelihood matrix.
##
## Estimate SE
## elpd_loo 2256.8 38.9
## p_loo 71.6 7.1
## looic -4513.5 77.8
## ------
## MCSE of elpd_loo is NA.
## MCSE and ESS estimates assume MCMC draws (r_eff in [0.7, 1.0]).
##
## Pareto k diagnostic values:
## Count Pct. Min. ESS
## (-Inf, 0.7] (good) 892 99.9% 765
## (0.7, 1] (bad) 1 0.1% <NA>
## (1, Inf) (very bad) 0 0.0% <NA>
## See help('pareto-k-diagnostic') for details.
Model predictions generally align with the observed data

📈 Results
We did not see a meaningful difference between the routine metabolic
rate for fish from the two salinity treatments.
Table S1
Table S1: Fixed effect Estimates (β) and 95%
Credible Intervals (95% CI)
| Predictor |
β |
95% CI |
| Intercept |
-2.545 |
[-2.659, -2.428] |
| shape_Intercept |
2.585 |
[2.45, 2.715] |
| temp_c |
-0.335 |
[-0.755, 0.087] |
| order_c |
0.002 |
[-0.002, 0.005] |
| light_dark_c |
0.134 |
[0.086, 0.182] |
| log_mass_c |
0.805 |
[0.609, 1.006] |
| salinity_group9 |
-0.096 |
[-0.259, 0.066] |
| shape_salinity_group9 |
0.177 |
[-0.025, 0.372] |
| shape_order_c |
-0.041 |
[-0.059, -0.023] |
Looking at the marginal mean MO2 for each salinity treatment
| salinity_group |
emmean |
lower.HPD |
upper.HPD |
| 0 |
0.079 |
0.070 |
0.088 |
| 9 |
0.071 |
0.064 |
0.080 |
These are the estimated mean constrast, we have exponentiated the log
estimate to get the fold-change. This means the model predicts that
sailianty group 0 has ~12% higher metabolic rate than group 9 (1.12)—but
this difference is not credible, because the interval for that
difference includes no difference (i.e. a ratio of 1.0).
| contrast |
estimate |
lower.HPD |
upper.HPD |
| salinity_group0 - salinity_group9 |
1.1 |
0.94 |
1.29 |
EEM contrasts for the two light phases, where -0.5 is dark, and 0.5
is light
| contrast |
estimate |
lower.HPD |
upper.HPD |
| light_dark_c0.5 - (light_dark_c-0.5) |
1.14 |
1.09 |
1.2 |
Here we we calculate the model-estimated marginal means for MO2 for a
unit increase in mass and transform this onto a fold-change scale. Where
log(mass) has be centered, a vaule of 0 represents the mean mass of
fish, and 1 corresponds to a fish with log(mass) = 1 unit above the mean
(i.e. 2.7 times large).
log(mass2) = log(mass1)+1
If you exponentiate both sides:
mass2 = mass1 x exp(1)
mass2 ≈ mass1 x 2.718
| contrast |
estimate |
lower.HPD |
upper.HPD |
| log_mass_c1 - log_mass_c0 |
2.23 |
1.86 |
2.76 |
Pulling the emmeans draws for our plot
MENTION R vaules with text from MS
SMR
Model structure
Here we will use a Bayesian Generalised Linear Mixed Model (GLMM)
with a Gamma distribution and a log link
Gamma(link = "log"), where the shape parameter (α) is also
modelled as a function of the salinity group,
shape ~ salinity_group. This models MO2 by salinity during
the SMR phase to see if the fish held at different salinities have
different SMRs. We have also added a few scaled predictors, that may
help describe variation in the data, such as fish mass (g; 0.21–1.6)
mean temperature (°C; 13.841–14.277), and the number of cycles over
which SMR was estimated (1–23). We allowed the the shape parameter (α)
to vary as a function of salinity_group to improve fit.
Prior selection
These are the default priors for the model. We will use these.
| prior |
class |
coef |
group |
resp |
dpar |
nlpar |
lb |
ub |
source |
|
b |
|
|
|
|
|
|
|
default |
|
b |
cycles_c |
|
|
|
|
|
|
default |
|
b |
log_mass_c |
|
|
|
|
|
|
default |
|
b |
salinity_group9 |
|
|
|
|
|
|
default |
|
b |
temp_mean_c |
|
|
|
|
|
|
default |
| student_t(3, -2.8, 2.5) |
Intercept |
|
|
|
|
|
|
|
default |
|
b |
|
|
|
shape |
|
|
|
default |
|
b |
salinity_group9 |
|
|
shape |
|
|
|
default |
| student_t(3, 0, 2.5) |
Intercept |
|
|
|
shape |
|
|
|
default |
Run model
Here we run the model, I have hashed this out because I have saved
the model for quick reloading.
⏭️ Skip this step if you have downloaded the saved
model ‘smr_mod_gamma.rds’
Here we reload the model
Model diagnostics
Checking model convergence


Using leave one out (loo) measure of fit, the model appears to
preform well, two Pareto k estimates falls outside the good range (0.7,
1]
##
## Computed from 14000 by 58 log-likelihood matrix.
##
## Estimate SE
## elpd_loo 134.6 11.0
## p_loo 11.0 4.8
## looic -269.2 22.0
## ------
## MCSE of elpd_loo is NA.
## MCSE and ESS estimates assume MCMC draws (r_eff in [0.8, 0.9]).
##
## Pareto k diagnostic values:
## Count Pct. Min. ESS
## (-Inf, 0.7] (good) 56 96.6% 4028
## (0.7, 1] (bad) 1 1.7% <NA>
## (1, Inf) (very bad) 1 1.7% <NA>
## See help('pareto-k-diagnostic') for details.
Model predictions generally align with the observed data, but there
is a lot of uncertainty around this estimate.

📈 Results
We did not see a meaningful difference between the routine metabolic
rate for fish from the two salinity treatments.
Table S2
Table S2: Fixed effect Estimates (β) and 95%
Credible Intervals (95% CI) from a Bayesian Generalised Linear Mixed
Model (GLMM) with a Gamma distribution and a log link
| Predictor |
β |
95% CI |
| Intercept |
-2.740 |
[-2.879, -2.603] |
| shape_Intercept |
2.010 |
[1.428, 2.532] |
| temp_mean_c |
-0.364 |
[-1.51, 0.802] |
| cycles_c |
-0.005 |
[-0.026, 0.018] |
| log_mass_c |
0.816 |
[0.597, 1.034] |
| salinity_group9 |
-0.086 |
[-0.283, 0.111] |
| shape_salinity_group9 |
0.117 |
[-0.733, 0.945] |
Looking at the marginal mean difference between salinity groups
| salinity_group |
emmean |
lower.HPD |
upper.HPD |
| 0 |
0.065 |
0.056 |
0.074 |
| 9 |
0.059 |
0.052 |
0.067 |
| contrast |
estimate |
lower.HPD |
upper.HPD |
| salinity_group0 - salinity_group9 |
1.09 |
0.89 |
1.32 |
Here we we calculate the model-estimated marginal means for SMR for a
unit increase in mass and transform this onto a fold-change scale. Where
log(mass) has be centered, a vaule of 0 represents the mean mass of
fish, and 1 corresponds to a fish with log(mass) = 1 unit above the mean
(i.e. 2.7 times large).
| contrast |
estimate |
lower.HPD |
upper.HPD |
| log_mass_c1 - log_mass_c0 |
2.26 |
1.84 |
2.84 |
Pulling the emmeans draws for our plot
Incremental regression analyses
Here we are following the methods Urbina et al. (2012)[1]
with an incremental regression analyses, in order to determine the best
fit for the MO2 vs O2 data
This analysis approach evaluates the relative ‘fit’ of each
polynomial order equation starting at zero and increasing to the third
order, permitting a mathematical assessment of whether fish were
oxyconforming or oxyregulatoring. If the data is best fitted/predicted
by a single linear relationship (1st-order polynomial) with a
positive slope, this would suggests the fish were oxyconforming.
Alternately, if the relationship is best modelled by a flat regression
(0th-order polynomial), or a higher order polynomial
(2nd or 3rd-order polynomial) the fish is likely
oxyregulatoring.
Building Bayesian regressions
Here we are using a Bayesian approach to model fitting with brm.
These models take a long time to run, so I have saved them and re-loaded
them to save time. I have also saved the summary data produced from the
models, to save time, you can simply skip the hashed code and input the
resulting summary data.
We will run our custom function,
bayes_incremental_regression_by_id.
Let’s make define the output directory
⏭️ Skip this step if you have already run this once,
or have downloaded the saved models or saved data files from GitHub
(that’s why its hashed out). ⌛This code takes a while to run
⌛
During this part of the script I received an error, ‘Caused by error
in socketConnection():’. I think the system may be hitting
a limit on the number of simultaneous socket connections. If you this
part of the code and also get this issue, try reducing the number of
parallel workers: plan(multisession, workers = 2), or run again after
the error.
Load all models and store in a list, will use a lot of memory. You
can also skip this step and load the resulting data frames below. I am
using the custom function load_rds, so we can compare them
and generate predictions.
⏭️ Skip this step if you have downloaded the saved
data pulled from these models have also hased this out,
bayes_reg_mods_fit.csv’ and ‘bayes_reg_mods_predictions.csv’. These are
in the mod-data directory.
Model fits
⏭️ Skip this step if you have downloaded 💿
bayes_reg_mods_fit.csv.
It gets model fit parameters loo and r2 using the custom function,
incremental_regression_bayes_fits. ⌛ This code takes a
while to run ⌛
Reading in this model fit data frame, in the case you did not load in
all the models.
Selecting the best fitting model
elpd_loo, or the expected log pointwise predictive density for
leave-one-out cross-validation, is a metric used in Bayesian model
evaluation to assess the predictive accuracy of a model. The elpd_loo is
an approximation of how well the model is expected to predict new data,
based on leave-one-out cross-validation. Higher elpd_loo values indicate
better predictive performance.
Model predictions
⏭️ Skip this step if you have downloaded 💿
bayes_reg_mods_predictions.csv.
It pulls our model predictions using a custom function
bayes_mod_predictions.
Reading in the predicted data
We are going to combined this with our best fitting model df, so we
know how they ranks for LOO.
📈 Results
Model selection summary
In most cases, the relationship between MO2 and DO was
best modelled with a 2nd-order polynomial (n = 22,
38% of fish), followed by a 3rd-order polynomial (n
= 15, 26%), 1st-order polynomial (n = 11, 19%), and
finally 0th-order polynomial (n = 10, 17%).
For the two most common models, 2nd- and
3rd-order polynomials, this could suggest the presence of a
critical oxygen threshold (Pcrit) where the relationship between
MO2 and O2 changes. To confirm the presence of a
Pcrit, we need to validated the shape of the polynomials (see Pcrit
model below). In any case, these type of models are indicative of
oxyregulator.
The next most common model was is 1st-order polynomial. In
the case of the 1st-order polynomials, it suggest the
presences of linear relationship between o2 and MO2, which is indicative
of oxyconformer. However, to be true evidence of a
oxyconformer this relationship should be positive (i.e. as O2
falls MO2 also falls). 13 of the 18 individuals best modelled
with a linear function had positive estimates with credible intervals
that did not overlap with zero (Table S3).
Lastly, 0th-order was the least common (n = 3,
5%), it suggests that MO2 does not show a statistically
significant dependence on the O2. In other words, the
metabolic rate does not adjust based on oxygen availability, and there
is no clear critical oxygen threshold (Pcrit) where the relationship
changes. This is indicative of a oxyregulator.
| best_model_name |
n |
percent |
| 0th-order polynomial |
10 |
17.24 |
| 1st-order polynomial |
11 |
18.97 |
| 2nd-order polynomial |
22 |
37.93 |
| 3rd-order polynomial |
15 |
25.86 |
Summary of fish best model with a linear function.
Table S3
Table S3: Ten fish that were best modelled with a
linear function, showing r2, and estimate (). Only two fish
had positive estimates with credible intervals that did not overlap with
zero, which are highlighted as conforming in the table. Thus in total,
13 of 58 fish showed sufficient evidence to be conforming.
| Fish ID |
r2 (CI) |
Estimate (CI) |
Percentage change |
Evidence of oxyconforming |
| d_9_25nov_3 |
0.197 (0.012 to 0.394) |
0.0011 ( 0.0003 to 0.0019) |
0.7437151 |
Conforming |
| a_9_22nov_4 |
0.312 (0.094 to 0.491) |
0.0008 ( 0.0004 to 0.0013) |
0.5739880 |
Conforming |
| b_9_22nov_1 |
0.231 (0.055 to 0.396) |
0.0005 ( 0.0002 to 0.0008) |
0.4310066 |
Conforming |
| d_9_25nov_2 |
0.330 (0.102 to 0.507) |
-0.0009 (-0.0013 to -0.0004) |
-0.7599381 |
Not conforming |
| a_0_25nov_1 |
0.137 (0.002 to 0.331) |
-0.0004 (-0.0007 to 0.0000) |
-0.2788575 |
Not conforming |
| c_0_22nov_3 |
0.072 (0.000 to 0.256) |
0.0005 (-0.0005 to 0.0016) |
0.3013443 |
Not conforming |
| a_0_24nov_3 |
0.058 (0.000 to 0.202) |
0.0005 (-0.0003 to 0.0012) |
0.2832654 |
Not conforming |
| c_9_27nov_2 |
0.068 (0.000 to 0.255) |
0.0003 (-0.0003 to 0.0008) |
0.1697994 |
Not conforming |
| a_9_22nov_1 |
0.084 (0.000 to 0.266) |
0.0003 (-0.0002 to 0.0008) |
0.2272965 |
Not conforming |
| b_0_25nov_2 |
0.108 (0.001 to 0.290) |
0.0003 ( 0.0000 to 0.0006) |
0.2275231 |
Not conforming |
| a_0_24nov_1 |
0.029 (0.000 to 0.134) |
0.0002 (-0.0005 to 0.0009) |
0.1072286 |
Not conforming |
Ploting all models
Data set with all slopes and which model was best
Saving all regression, and highlighting the model that has the best
fit, based on AIC values. This is called
combined_reg_plots.pdf
Getting a plot for each best fit regression, and overlaying a global
model for that model type.
Here we are grouping fish by best fitting model and getting an
average trend. I have hashed the code so you don’t need to re-run the
models
⏭️ Skip this step if you have downloaded the global
models ‘.rds’ in the ‘bayes-regs-global’ folder
⏭️ Skip this step if you have downloaded the
global_models_pred_df.csv
Load data frame
O₂crit model
We will calculate O₂crit using Chabot method and function
calcO2crit.
This function uses the fifth percentile of the MO2 values
observed at dissolved oxygen levels ≥ 80% air saturation as the
criterion to assess low MO2 values. The algorithm then
identifies all the MO2 measurements greater than this
minimally acceptable MO2 value. Within this sub-set, it
identifies the MO22 measurement made at the lowest DO and
thereafter considers this DO as candidate for breakpoint (named pivotDO
in the script). A regression is then calculated using observations at DO
levels < pivotDO, and a first estimate of O2crit is
calculated as the intersection of this regression line with the
horizontal line representing SMR. The script then goes through
validation steps to ensure that the slope of the regression is not so
low that the line, projected to normoxic DO levels, passes below any
MO2 values observed in normoxia. It also ensures that the
intercept is not greater than zero. Corrective measures are taken if
such problems are encountered.
lowestMO2 default is the
quantile(MO2[DO >= 80], p=0.05). It is used to segment
the data and locate the pivotDO.
O₂crit numerical rules
We applied a numerical rule to asses if a O2crit was
observed. Specifically, we filtered for only cases were at the lowest O₂
value three consecutive MO₂ measures full below our SMR and fifth
percentile of the MO2 values observed at dissolved O2 levels > 80%.
In the model output these are called nb_mo2_conforming points.
## [1] "Based on this rule there are 16 fish with possible O₂crits."
Visual inspection
We conducted visual inspection of all 58 fish to determine if
O2crits were present. We have loaded this as a data frame
💿 o2crit_check
For this visual inspection, we grouped fish into “no”, “maybe” or
“yes”, based on the certainty at which we observed a O2crits.
In the case of yes or maybe, we also estimate dissolved oxygen
percentage. All authors did this independently.
📈 Results
Let’s figure out how consistent the categorisation was, and what the
majority response was. There were 35 cases with no disagreements
(60.34%), 23 cases with one or more disagreements (39.66%).
| cat_disagreement |
n |
percent |
| 0 |
35 |
60.34 |
| 1 |
23 |
39.66 |
O₂crit numbers
We will now check to see which fish have O2crit based on
the numerical and visual inspections.
There are eight fish that both numerically and visually were
determined to have a O2crit. Two fish with a visually
confirmed O2crit, that did not meet the numerical criteria.
Eight fish meet the numerical criteria, but did not pass the visual
inspection.
## $Shared
## [1] "a_0_26nov_4" "b_0_24nov_1" "b_0_25nov_1" "b_0_25nov_3" "b_0_26nov_1"
## [6] "b_9_21nov_1" "b_9_21nov_2" "b_9_21nov_3"
##
## $Unique_to_visual
## [1] "c_0_21nov_4" "d_0_21nov_2"
##
## $Unique_to_numerical
## [1] "a_9_21nov_3" "b_0_24nov_2" "b_0_26nov_3" "b_9_22nov_1" "c_0_21nov_2"
## [6] "c_9_24nov_2" "d_0_21nov_3" "d_9_25nov_3"
How many per salinity treatment
📈 Results
Looking at mean O2crit estimates.
| n_o2crit |
mean_o2crit |
min_o2crit |
max_o2crit |
mean_mass |
mean_rel_mass |
sd_mass |
sd_rel_mass |
| 8.00 |
24.94 |
19.10 |
32.00 |
0.46 |
0.85 |
0.18 |
0.34 |
| mean_min_do |
sd_min_do |
min_min_do |
| 13.12 |
3.23 |
8.82 |
| salinity_group |
n_o2crit |
mean_o2crit |
min_o2crit |
max_o2crit |
mean_mass |
| 0 |
5 |
25.32 |
19.1 |
32.0 |
0.3540000 |
| 9 |
3 |
24.30 |
21.7 |
28.9 |
0.6466667 |
Comapring to past data
Here, we have recreated a similar plot to that presented in Urbina,
Glover, and Forster (2012)[1] and have extracted the mean
level data from Figure 1a using the metaDigitise package in
R[3]. This data is called urbina_et_al_2012. This allows us
to compare the differences in Mo2 and the relationship between Mo2 and
O2.
First making a binned data frame to match Urbina, Glover, and Forster
(2012) as closely as possible.
📚 References
[1] Claireaux, G. and Chabot, D. (2016) Responses by
fishes to environmental hypoxia: integration through Fry’s concept of
aerobic metabolic scope. Journal of Fish Biology https://doi.org/10.1111/jfb.12833
[2] Urbina MA, Glover CN, and Forster ME, (2012) A novel
oxyconforming response in the freshwater fish Galaxias
maculatus. Comparative Biochemistry and Physiology Part A:
Molecular & Integrative Physiology. https://doi.org/10.1016/j.cbpa.2011.11.011
[3] Pick JL, Nakagawa S, and Noble DWA (2018)
Reproducible, flexible and high-throughput data extraction from primary
literature: The metaDigitise r package. https://doi.org/10.1111/2041-210X.13118
LS0tDQp0aXRsZTogIlRoZSByb2xlIG9mIG9zbW9yZXNwaXJhdG9yeSBjb21wcm9taXNlIGluIGh5cG94aWEgdG9sZXJhbmNlIG9mIHRoZSBwdXJwb3J0ZWRseSBveHljb25mb3JtaW5nIHRlbGVvc3QgR2FsYXhpYXMgbWFjdWxhdHVzIg0KYXV0aG9yOiAiSmFrZSBNYXJ0aW4iDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiAlWScpYCINCm91dHB1dDoNCiAgIyBwZGZfZG9jdW1lbnQ6DQogICMgICB0b2M6IHRydWUNCiAgIyAgIGxhdGV4X2VuZ2luZTogeGVsYXRleA0KICAjICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICMgICBwYW5kb2NfYXJnczogWyItLXZhcmlhYmxlPWRvY3VtZW50Y2xhc3M6YXJ0aWNsZSJdDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGRlcHRoOiA0DQogICAgbnVtYmVyX3NlY3Rpb25zOiBubw0KICAgIHRoZW1lOiAgY29zbW8NCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDogeWVzDQogICAgdG9jX2RlcHRoOiA0DQprbml0OiB8DQogIChmdW5jdGlvbihpbnB1dCwgLi4uKSB7DQogICAgcm1hcmtkb3duOjpyZW5kZXIoDQogICAgICBpbnB1dCwNCiAgICAgIG91dHB1dF9maWxlID0gcGFzdGUwKA0KICAgICAgICdpbmRleC5odG1sJw0KICAgICAgKSwNCiAgICAgIGVudmlyID0gZ2xvYmFsZW52KCkNCiAgICApDQogIH0pDQotLS0NCg0KWyFbTGljZW5zZTogQ0MgQlkgNC4wXShodHRwczovL2ltZy5zaGllbGRzLmlvL2JhZGdlL0xpY2Vuc2UtQ0MlMjBCWSUyMDQuMC1saWdodGdyZXkuc3ZnKV0oaHR0cHM6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL2J5LzQuMC8pIA0KDQo8IS0tIENvbW1lbnQgb3V0IHRoZSBsaWNlbnNlIHdoZW4ga25pdHRpbmcgdG8gUERGIC0tPg0KDQo8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+DQoNCiMg8J+TlSBSRUFEIE1FDQoNCjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT4NCg0KKirwn5qnIFVOUFVCTElTSEVEIEFORCBPTkdPSU5HIGV4YW1wbGUg8J+apyoqDQpUaGUgZGF0YSBpbiB0aGlzIHNjcmlwdCBhcmUgY3VycmVudGx5ICoqdW5wdWJsaXNoZWQqKiwgYW5kIHRoZSAqKmFuYWx5c2lzIGlzIG9uZ29pbmcqKi4gU29tZSBzZWN0aW9ucyBtYXkgYmUgaW5jb21wbGV0ZS4gVGhpcyBzY3JpcHQgaGFzIGJlZW4gbWFkZSBwdWJsaWNseSBhdmFpbGFibGUgdG8gZmFjaWxpdGF0ZSBzaGFyaW5nIHdpdGggY29sbGFib3JhdG9ycyBhbmQgY29sbGVhZ3VlcyB3aG8gYXJlIGludGVyZXN0ZWQgaW4gdGhlIHByb2dyZXNzIG9mIHRoZSBwcm9qZWN0IGFuZCB0byBlbnN1cmUgdHJhbnNwYXJlbmN5Lg0KDQoqKlNVTU1BUlkqKg0KVGhpcyBSIGNvZGUgZXN0aW1hdGVzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBveHlnZW4gY29uc3VtcHRpb24gKE1P4oKCKSBhbmQgZGlzc29sdmVkIG94eWdlbiBzYXR1cmF0aW9uIChETykgaW4gdGhlIENvbW1vbiBHYWxheGlhcyAoKkdhbGF4aWFzIG1hY3VsYXR1cyopLiBJdCBhbHNvIGVzdGltYXRlcyB0aGUgY3JpdGljYWwgb3h5Z2VuIHNhdHVyYXRpb24gdmFsdWUgZm9yIGFlcm9iaWMgbWV0YWJvbGlzbSBPPHN1Yj4yY3JpdDwvc3ViPiwgY29tbW9ubHkgZGVmaW5lZCBhcyB0aGUgdGhyZXNob2xkIGJlbG93IHdoaWNoIHRoZSBveHlnZW4gY29uc3VtcHRpb24gcmF0ZSBjYW4gbm8gbG9uZ2VyIGJlIHN1c3RhaW5lZC4gVGhlIGFzc29jaWF0ZWQgYXJ0aWNsZSBpcyB0aXRsZWQgKiJUaGUgcm9sZSBvZiBvc21vcmVzcGlyYXRvcnkgY29tcHJvbWlzZSBpbiBoeXBveGlhIHRvbGVyYW5jZSBvZiB0aGUgcHVycG9ydGVkbHkgb3h5Y29uZm9ybWluZyB0ZWxlb3N0IEdhbGF4aWFzIG1hY3VsYXR1cy4iKiBJZiB5b3UgYXJlIHJlYWRpbmcgdGhlIEhUTUwgdmVyc2lvbiBvZiB0aGlzIHNjcmlwdCwgY2xpY2sgdGhlIGBDb2RlYCBidXR0b24gaW4gdGhlIHRvcCByaWdodCB0byBkb3dubG9hZCB0aGUgYC5SbWRgIGZpbGUuDQoNCioqQUlNKioNClRoZSBhcnRpY2xlIGFpbXMgdG8gdGVzdCB3aGV0aGVyICpHYWxheGlhcyBtYWN1bGF0dXMqIGNhbiBtYWludGFpbiBveHlnZW4gY29uc3VtcHRpb24gKE1P4oKCKSBhcyBhbWJpZW50IERPIGRlY2xpbmVzIGFuZCwgaWYgc28sIGF0IHdoYXQgbGV2ZWwgaXQgcmVhY2hlcyB0aGUgY3JpdGljYWwgb3h5Z2VuIHNhdHVyYXRpb24gdmFsdWUgZm9yIGFlcm9iaWMgbWV0YWJvbGlzbSAoTzxzdWI+MmNyaXQ8L3N1Yj4pLg0KDQoqKkFVVEhPUlMqKg0KVGltb3RoeSBELiBDbGFyayBeW2FdXg0KTWFyeWFuZSBHcmFkaXRvIF5bYV1eDQpFbGl6YWJldGggQy4gSG9vdHMgXlthXV4NCkx1aXMgTC4gS3VjaGVubcO8bGxlciBeW2FdXg0KSmFrZSBNLiBNYXJ0aW4gXlthLGJdXg0KDQoqKkFGRklMSUFUSU9OUyoqDQpbYV0gU2Nob29sIG9mIExpZmUgYW5kIEVudmlyb25tZW50YWwgU2NpZW5jZXMsIERlYWtpbiBVbml2ZXJzaXR5LCBHZWVsb25nLCBWSUMsIEF1c3RyYWxpYVwNCltiXSBEZXBhcnRtZW50IG9mIFdpbGRsaWZlLCBGaXNoIGFuZCBFbnZpcm9ubWVudGFsIFN0dWRpZXMsIFN3ZWRpc2ggVW5pdmVyc2l0eSBvZiBBZ3JpY3VsdHVyYWwgU2NpZW5jZXMsIFVtZcOlLCBTd2VkZW5cDQoNCioqQ09OVFJJQlVUT1IgUk9MRVMqKg0K8J+apyAqKipUbyBiZSBhZGRlZCoqKiDwn5qnDQoqQmFzZWQgb24gdGhlIENvbnRyaWJ1dG9yIFJvbGVzIFRheG9ub215IChDUmVkaVQpKg0KDQoqKkRJU0NMQUlNRVIqKg0KSSAoSmFrZSBNYXJ0aW4pIGFtIGR5c2xleGljLiBJIGhhdmUgbWFkZSBhbiBlZmZvcnQgdG8gcmV2aWV3IHRoZSBzY3JpcHQgZm9yIGdyYW1tYXRpY2FsIGVycm9ycywgYnV0IHNvbWUgd2lsbCBsaWtlbHkgcmVtYWluLiBJIGFwb2xvZ2lzZS4gUGxlYXNlIGZlZWwgZnJlZSB0byByZWFjaCBvdXQgdXNpbmcgdGhlIGNvbnRhY3QgZGV0YWlscyBiZWxvdyBpZiBhbnl0aGluZyBpcyB1bmNsZWFyLg0KDQo8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+DQoNCiMg8J+TpyBDb250YWN0DQoNCjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT4NCg0KKipKYWtlIE0uIE1hcnRpbioqDQoNCvCfk6cgKipFbWFpbDoqKiBbamFrZS5tYXJ0aW5cQGRlYWtpbi5lZHUuYXVdKG1haWx0bzpqYWtlLm1hcnRpbkBkZWFraW4uZWR1LmF1KQ0KDQrwn5OnICoqQWx0IEVtYWlsOioqIFtqYWtlLm1hcnRpbi5yZXNlYXJjaFxAZ21haWwuY29tXShtYWlsdG86amFrZS5tYXJ0aW4ucmVzZWFyY2hAZ21haWwuY29tKQ0KDQrwn4yQICoqV2ViOioqIFtqYWtlbWFydGluLm9yZ10oaHR0cHM6Ly9qYWtlbWFydGluLm9yZy8pDQoNCvCfkJkgKipHaXRIdWIqKjogW0pha2VNYXJ0aW5SZXNlYXJjaF0oaHR0cHM6Ly9naXRodWIuY29tL0pha2VNYXJ0aW5SZXNlYXJjaCkNCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQojIPCfk5EgU2hhcmluZy9hY2Nlc3NpbmcgYW5kIGNpdGluZw0KDQo8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+DQoNCjEuICAqKkxpY2Vuc2VzL3Jlc3RyaWN0aW9ucyBwbGFjZWQgb24gdGhlIGRhdGE6KiogQ0MtQlkgNC4wDQoNCjIuICAqKkxpbmsgdG8gdGhlIGFzc29jaWF0ZWQgcHVibGljYXRpb246KipcDQogICAg8J+apyAqKipUbyBiZSBhZGRlZCoqKiDwn5qnDQoNCjMuICAqKlJlY29tbWVuZGVkIGNpdGF0aW9uIGZvciB0aGlzIGRhdGE6KipcDQoNClRpbW90aHkgRC4gQ2xhcmssIE1hcnlhbmUgR3JhZGl0bywgRWxpemFiZXRoIEhvb3RzLCBMdWlzIEwuIEt1Y2hlbm3DvGxsZXIsIEpha2UgTS4gTWFydGluICgyMDI1KS4gVGhlIHJvbGUgb2Ygb3Ntb3Jlc3BpcmF0b3J5IGNvbXByb21pc2UgaW4gaHlwb3hpYSB0b2xlcmFuY2Ugb2YgdGhlIHB1cnBvcnRlZGx5IG94eWNvbmZvcm1pbmcgdGVsZW9zdCAqR2FsYXhpYXMgbWFjdWxhdHVzKi4gT1NGIERPSToxMC4xNzYwNS9PU0YuSU8vR0ZYQ0EgKExhc3QgVXBkYXRlZDogMjAyNS0wNS0yOCAxMjoyOCBQTSkNCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQojIPCfk6YgUmVxdWlyZWQgcGFja2FnZXMgYW5kIGtuaXQgc2V0dGluZ3MNCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQpBIGxpc3Qgb2YgdGhlIHJlcXVpcmVkIHBhY2thZ2VzIHRvIHJ1biB0aGUgc2NyaXB0Lg0KDQpgYGB7ciBzZXR1cH0NCg0KIyAtLS0tLSBQYWNrYWdlcyAtLS0tLS0NCmlmICghcmVxdWlyZU5hbWVzcGFjZSgicGFjbWFuIiwgcXVpZXRseSA9IFRSVUUpKSBpbnN0YWxsLnBhY2thZ2VzKCJwYWNtYW4iKQ0KDQojIC0tLS0gTGlzdCBvZiByZXF1aXJlZCBwYWNrYWdlcyAtLS0tDQpwa2dzIDwtIGMoDQogICMgLS0tLS0gRGF0YSBWaXN1YWxpc2F0aW9uIC0tLS0tDQogICJnZ3RoZW1lcyIsICJiYXllc3Bsb3QiLCAiZ3QiLCAiZ3RzdW1tYXJ5IiwgInBsb3RseSIsICJxcXBsb3RyIiwgImdyaWRFeHRyYSIsDQogIA0KICAjIC0tLS0tIFRpZHkgRGF0YSBhbmQgV3JhbmdsaW5nIC0tLS0tDQogICJ0aWR5dmVyc2UiLCAiamFuaXRvciIsICJyZWFkeGwiLCAiYnJvb20ubWl4ZWQiLCAiZGF0YS50YWJsZSIsICJobXMiLCAiZGV2dG9vbHMiLA0KICAibWNsdXN0IiwNCiAgDQogICMgLS0tLS0gTW9kZWxsaW5nIGFuZCBTdGF0aXN0aWNhbCBBbmFseXNpcyAtLS0tLQ0KICAiYnJtcyIsICJyc3RhbiIsICJtYXJnaW5hbGVmZmVjdHMiLCAicGVyZm9ybWFuY2UiLCAiZW1tZWFucyIsDQogICJ0aWR5YmF5ZXMiLCAicmVzcGlyb21ldHJ5IiwgImZ1dHVyZSINCikNCg0KIyAtLS0tIEluc3RhbGwgYW5kIGxvYWQgYWxsIHBhY2thZ2VzIHVzaW5nIHBhY21hbiAtLS0tDQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMoDQogIHBhY21hbjo6cF9sb2FkKGNoYXIgPSBwa2dzLCBpbnN0YWxsID0gVFJVRSkNCikNCg0KIy0tLS0tLS1rbml0ZXIgc2VldHRpbmctLS0tLS0tLS0tLQ0KDQprbml0cjo6b3B0c19jaHVuayRzZXQoDQogIGVjaG8gPSBGQUxTRSwgIyBvbmx5IGZvciBQREYga25pdA0KICBtZXNzYWdlID0gRkFMU0UsDQogIHdhcm5pbmcgPSBGQUxTRSwgIyBubyB3YXJuaW5ncw0KICBjYWNoZSA9IFRSVUUsIyBjYWNoZWluZyB0byBzYXZlIHRpbWUgd2hlbiBrbml0aW5nDQogIHRpZHkgPSBUUlVFLA0KICBmaWcuYWxpZ24gPSAiY2VudGVyIiANCikNCmBgYA0KDQoNCjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT4NCg0KIyDwn5SnIEN1c3RvbSBmdW5jdGlvbnMNCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQpIZXJlIGFyZSBzb21lIGN1c3RvbSBmdW5jdGlvbnMgdXNlZCB3aXRoaW4gdGhpcyBzY3JpcHQuDQoNCmBiYXllc19pbmNyZW1lbnRhbF9yZWdyZXNzaW9uX2J5X2lkKClgOiBBIGN1c3RvbSBmdW5jdGlvbiB0byBidWlsZCBCYXllc2lhbiBpbmNyZW1lbnRhbCByZWdyZXNzaW9ucy4gSXQgaXMgZGVzaWduZWQgdG8gcnVuIGEgbGlzdCBvZiBzdWJncm91cCBtb2RlbHMgKElEcykgaW4gcGFyYWxsZWwgdXNpbmcgNCBjb3Jlcy4gVGhlIGZ1bmN0aW9uIHVzZXMgYGJybSgpYCB3aXRoIGEgR2F1c3NpYW4gZXJyb3IgZGlzdHJpYnV0aW9uLg0KDQoqKlVzZSoqOlwNClRoZSBmdW5jdGlvbiBhY2NlcHRzIHRoZSBmb2xsb3dpbmcgYXJndW1lbnRzOlwNCi0gYGlkX2lgOiBBIGdyb3VwaW5nIGZhY3RvciBvciBJRCB1c2VkIHRvIGZpbHRlciB0aGUgZGF0YSBmb3IgZWFjaCByZWdyZXNzaW9uLiBJZiBub25lIGlzIHByb3ZpZGVkLCB0aGUgZnVuY3Rpb24gdXNlcyB0aGUgZW50aXJlIGRhdGFzZXQuXA0KLSBgaWRfbmFtZWA6IFRoZSBjb2x1bW4gbmFtZSAoYXMgYSBjaGFyYWN0ZXIgc3RyaW5nKSBjb3JyZXNwb25kaW5nIHRvIHRoZSBncm91cGluZyBmYWN0b3IgaW4gdGhlIGRhdGEgZnJhbWUuIElmIG5vdCBwcm92aWRlZCwgdGhlIGZ1bmN0aW9uIHVzZXMgYWxsIGRhdGEuXA0KLSBgZGF0YWA6IFRoZSBkYXRhIGZyYW1lIGNvbnRhaW5pbmcgdGhlIHZhcmlhYmxlcyBmb3IgYW5hbHlzaXMuXA0KLSBgcHJlZGljdG9yYDogVGhlIHByZWRpY3RvciB2YXJpYWJsZSBvZiBpbnRlcmVzdC5cDQotIGByZXNwb25zZWA6IFRoZSByZXNwb25zZSB2YXJpYWJsZSBvZiBpbnRlcmVzdC5cDQotIGBzZWVkX251bWJlcmA6IEEgcmFuZG9tIHNlZWQgdmFsdWUgZm9yIG1vZGVsIHJlcHJvZHVjaWJpbGl0eS5cDQotIGBzYXZlX21vZGVsc2A6IEEgbG9naWNhbCBhcmd1bWVudCBpbmRpY2F0aW5nIHdoZXRoZXIgdG8gc2F2ZSB0aGUgbW9kZWwgb3V0cHV0cyAoYFRSVUVgIG9yIGBGQUxTRWApLlwNCi0gYG1vZF9vdXRwdXRfd2RgOiBUaGUgb3V0cHV0IGRpcmVjdG9yeSB3aGVyZSBtb2RlbCBgLnJkc2AgZmlsZXMgc2hvdWxkIGJlIHNhdmVkICh1c2VkIG9ubHkgaWYgYHNhdmVfbW9kZWxzID0gVFJVRWApLg0KDQpgYGB7cn0NCiMgSW5zdGVhZCB3ZSBjb3VsZCBhbHNvIHVzZSBhIGRpc3RyaWJ1dGlvbmFsIHJlZ3Jlc3Npb24gYXBwcm9hY2gsIGJ5IHNwZWNpZmljYWxseSBtb2RlbGxpbmcgdGhlIHZhcmlhbmNlIGJ5IERPIChlLmcuIHNpZ21hIH4gRE8pLiBXZWlnaHRpbmcgbWF5IG5vdCBiZSByZXF1aXJlZCBpbiB0aGlzIGNhc2UsIEkgZG9uJ3QgdGhpbmsgaGlnaGVyIGRlbnNpdHkgb2YgdmFsdWVzIGluIGEgZ2l2ZW4gc3BhY2Ugd2lsbCBlZmZlY3QgQmF5ZXNpYW4gZXN0aW1hdGVzIGxpa2UgaXQgZG9lcyBpbiBmcmVxdWVudGlzdCBtb2RlbHMuIFNlZSBkaXNjb3Vyc2UgaHR0cHM6Ly9kaXNjb3Vyc2UubWMtc3Rhbi5vcmcvdC93ZWlnaHRzLWluLWJybS80Mjc4ICAgDQoNCmJheWVzX2luY3JlbWVudGFsX3JlZ3Jlc3Npb25fYnlfaWQgPC0gZnVuY3Rpb24oaWRfaSwgaWRfbmFtZSwgZGF0YSwgcHJlZGljdG9yLCByZXNwb25zZSwgc2VlZF9udW1iZXIsIHNhdmVfbW9kZWxzLCBtb2Rfb3V0cHV0X3dkKSB7DQogICMgSW5pdGlhdGUgYW4gZW1wdHkgbGlzdCB0byBzdG9yZSBtb2RlbHMNCiAgbW9kZWxzIDwtIGxpc3QoKQ0KICANCiAgIyBDaGVjayBpZiBpZF9uYW1lIGlzIG1pc3NpbmcsIE5VTEwsIG9yIGJsYW5rLCBhbmQgYXNzaWduIE5BIGlmIHNvDQogIGlmIChtaXNzaW5nKGlkX25hbWUpIHx8IGlzLm51bGwoaWRfbmFtZSkgfHwgaWRfbmFtZSA9PSAiIikgew0KICAgIGlkX25hbWUgPC0gTkENCiAgfQ0KICANCiAgIyBDaGVjayBpZiBpZF9pIGlzIG1pc3NpbmcsIE5VTEwsIG9yIGJsYW5rLCBhbmQgYXNzaWduIE5BIGlmIHNvDQogIGlmIChtaXNzaW5nKGlkX2kpIHx8IGlzLm51bGwoaWRfaSkgfHwgaWRfaSA9PSAiIikgew0KICAgIGlkX25hbWUgPC0gTkENCiAgfQ0KICANCiAgIyBGaWx0ZXIgZGF0YSBmb3IgdGhlIGN1cnJlbnQgSUQgaWYgaWRfbmFtZSBpcyBnaXZlbiBhcyBhIGZhY3RvciBvciBjaGFyYWN0ZXIgYW5kIGlkX2kgaXMgZGVmaW5lZA0KICBkZl9pIDwtIGRhdGEgJT4lDQogICAgZHBseXI6OmZpbHRlcigNCiAgICAgIGlmICghaXMubmEoaWRfaSkgJiYgKGlzLmZhY3RvcihkYXRhW1tpZF9uYW1lXV0pIHx8IGlzLmNoYXJhY3RlcihkYXRhW1tpZF9uYW1lXV0pKSkgew0KICAgICAgICAhIXJsYW5nOjpzeW0oaWRfbmFtZSkgPT0gaWRfaQ0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgVFJVRQ0KICAgICAgfQ0KICAgICkNCiAgDQogICMgRHluYW1pY2FsbHkgY3JlYXRlIGZvcm11bGFzDQogIGZvcm11bGFfbG1fMCA8LSByZWZvcm11bGF0ZSgiMSIsIHJlc3BvbnNlKQ0KICBmb3JtdWxhX2xtXzEgPC0gcmVmb3JtdWxhdGUocHJlZGljdG9yLCByZXNwb25zZSkNCiAgZm9ybXVsYV9sbV8yIDwtIHJlZm9ybXVsYXRlKHNwcmludGYoInBvbHkoJXMsIDIpIiwgcHJlZGljdG9yKSwgcmVzcG9uc2UpDQogIGZvcm11bGFfbG1fMyA8LSByZWZvcm11bGF0ZShzcHJpbnRmKCJwb2x5KCVzLCAzKSIsIHByZWRpY3RvciksIHJlc3BvbnNlKQ0KICANCiAgIyBGaXQgYW5kIHN0b3JlIG1vZGVscyBpbiB0aGUgbGlzdA0KICBtb2RlbHNbW3Bhc3RlMChpZF9pLCAiX2xtXzAiKV1dIDwtIGJybSgNCiAgICBiZihmb3JtdWxhX2xtXzAsIGZhbWlseSA9IGdhdXNzaWFuKCkpLCANCiAgICBkYXRhID0gZGZfaSwgY29yZXMgPSA0LCBzZWVkID0gc2VlZF9udW1iZXIsIHNhdmVfcGFycyA9IHNhdmVfcGFycyhhbGwgPSBzYXZlX21vZGVscyksDQogICAgc2FtcGxlX3ByaW9yID0gRkFMU0UsIHNpbGVudCA9IFRSVUUsIGZpbGUgPSBwYXN0ZTAobW9kX291dHB1dF93ZCwgIi8iLCBpZF9pLCAiX2xtXzAiKQ0KICApDQogIA0KICBtb2RlbHNbW3Bhc3RlMChpZF9pLCAiX2xtXzEiKV1dIDwtIGJybSgNCiAgICBiZihmb3JtdWxhX2xtXzEsIGZhbWlseSA9IGdhdXNzaWFuKCkpLCANCiAgICBkYXRhID0gZGZfaSwgY29yZXMgPSA0LCBzZWVkID0gc2VlZF9udW1iZXIsIHNhdmVfcGFycyA9IHNhdmVfcGFycyhhbGwgPSBzYXZlX21vZGVscyksDQogICAgc2FtcGxlX3ByaW9yID0gRkFMU0UsIHNpbGVudCA9IFRSVUUsIGZpbGUgPSBwYXN0ZTAobW9kX291dHB1dF93ZCwgIi8iLCBpZF9pLCAiX2xtXzEiKQ0KICApDQogIA0KICBtb2RlbHNbW3Bhc3RlMChpZF9pLCAiX2xtXzIiKV1dIDwtIGJybSgNCiAgICBiZihmb3JtdWxhX2xtXzIsIGZhbWlseSA9IGdhdXNzaWFuKCkpLCANCiAgICBkYXRhID0gZGZfaSwgY29yZXMgPSA0LCBzZWVkID0gc2VlZF9udW1iZXIsIHNhdmVfcGFycyA9IHNhdmVfcGFycyhhbGwgPSBzYXZlX21vZGVscyksDQogICAgc2FtcGxlX3ByaW9yID0gRkFMU0UsIHNpbGVudCA9IFRSVUUsIGZpbGUgPSBwYXN0ZTAobW9kX291dHB1dF93ZCwgIi8iLCBpZF9pLCAiX2xtXzIiKQ0KICApDQogIA0KICBtb2RlbHNbW3Bhc3RlMChpZF9pLCAiX2xtXzMiKV1dIDwtIGJybSgNCiAgICBiZihmb3JtdWxhX2xtXzMsIGZhbWlseSA9IGdhdXNzaWFuKCkpLCANCiAgICBkYXRhID0gZGZfaSwgY29yZXMgPSA0LCBzZWVkID0gMTQzMDE5LCBzYXZlX3BhcnMgPSBzYXZlX3BhcnMoYWxsID0gc2F2ZV9tb2RlbHMpLA0KICAgIHNhbXBsZV9wcmlvciA9IEZBTFNFLCBzaWxlbnQgPSBUUlVFLCBmaWxlID0gcGFzdGUwKG1vZF9vdXRwdXRfd2QsICIvIiwgaWRfaSwgIl9sbV8zIikNCiAgKQ0KICANCiAgIyBSZXR1cm4gdGhlIGxpc3Qgb2YgbW9kZWxzIGZvciB0aGUgY3VycmVudCBJRA0KICByZXR1cm4obW9kZWxzKQ0KfQ0KYGBgDQoNCmBsb2FkX3JkczkoKWA6IEEgY3VzdG9tIGZ1bmN0aW9uIHRvIGxvYWQgYWxsIHJkcyBtb2RlbHMgaW4gYSBkaXJlY3RvcnkgYW5kIHN0b3JlIGluIGEgbGlzdC4gVGFrZXMgYSBkaXJlY3Rvcnkgd2l0aCBgLnJkc2AgZmlsZXMNCg0KYGBge3J9DQpsb2FkX3JkcyA8LSBmdW5jdGlvbihtb2RlbF9kdykgew0KICAjIExpc3QgYWxsIC5yZHMgZmlsZXMgaW4gdGhlIGRpcmVjdG9yeQ0KICBtb2RlbF9maWxlX2xpc3QgPC0gbGlzdC5maWxlcyhwYXRoID0gbW9kZWxfZHcsIHBhdHRlcm4gPSAiXFwucmRzJCIsIGZ1bGwubmFtZXMgPSBUUlVFKQ0KICANCiAgIyBTdHJpcCBleHRlbnNpb25zIGFuZCBnZXQgbmFtZXMNCiAgbW9kZWxfbmFtZXMgPC0gdG9vbHM6OmZpbGVfcGF0aF9zYW5zX2V4dChiYXNlbmFtZShtb2RlbF9maWxlX2xpc3QpKQ0KICANCiAgIyBSZWFkIGFsbCAucmRzIGZpbGVzIGludG8gYSBuYW1lZCBsaXN0DQogIG1vZGVsX3N0b3JlX2xpc3QgPC0gc2V0TmFtZXMobGFwcGx5KG1vZGVsX2ZpbGVfbGlzdCwgcmVhZFJEUyksIG1vZGVsX25hbWVzKQ0KICANCiAgcmV0dXJuKG1vZGVsX3N0b3JlX2xpc3QpDQp9DQpgYGANCg0KYGluY3JlbWVudGFsX3JlZ3Jlc3Npb25fYmF5ZXNfZml0cygpYDogQSBjdXN0b20gZnVuY3Rpb24gZm9yIHB1bGxpbmcgbW9kZWwgZml0cywgbG9vIGFuZCByMiB1c2luZyBgbG9vKClgIGFuZCBgYmF5ZXNfUjIoKWAsIHJlc3BlY3RpdmVseS4gVGFrZXMgYSBsaXN0IG9mIGBicm1gIG1vZGVscy4NCg0KYGBge3J9DQojIERlZmluZSBGdW5jdGlvbiB0byBQcm9jZXNzIHRoZSBkYXRhIGZvciBlYWNoIElEDQppbmNyZW1lbnRhbF9yZWdyZXNzaW9uX2JheWVzX2ZpdHMgPC0gZnVuY3Rpb24obW9kZWxzKSB7DQogIA0KICBsb29fcmVzdWx0c19saXN0IDwtIGxpc3QoKQ0KICANCiAgIyBJdGVyYXRlIG92ZXIgdGhlIG5hbWVzIG9mIHRoZSBtb2RlbHMNCiAgZm9yIChtb2RfbmFtZSBpbiBuYW1lcyhtb2RlbHMpKSB7DQogICAgIyBFeHRyYWN0IHRoZSBtb2RlbA0KICAgIG1vZF9pIDwtIG1vZGVsc1tbbW9kX25hbWVdXQ0KICAgIA0KICAgICMgQ29tcHV0ZSBMT08gcmVzdWx0cw0KICAgIG1vZF9sb29fcmVzdWx0c19pIDwtIGxvbzo6bG9vKG1vZF9pKQ0KICAgIA0KICAgICMgRXh0cmFjdCByZWxldmFudCBMT08gbWV0cmljcw0KICAgIGVscGRfbG9vX2kgPC0gbW9kX2xvb19yZXN1bHRzX2kkZWxwZF9sb28NCiAgICBwX2xvb19pIDwtIG1vZF9sb29fcmVzdWx0c19pJHBfbG9vDQogICAgbG9vaWNfaSA8LSBtb2RfbG9vX3Jlc3VsdHNfaSRsb29pYw0KICAgIA0KICAgICMgQ3JlYXRlIGEgZGF0YSBmcmFtZSB3aXRoIG1ldHJpY3MNCiAgICBkZl9pIDwtIGRhdGEuZnJhbWUoDQogICAgICBlbHBkX2xvbyA9IGVscGRfbG9vX2ksDQogICAgICBwX2xvbyA9IHBfbG9vX2ksDQogICAgICBsb29pYyA9IGxvb2ljX2ksDQogICAgICBtb2RlbCA9IG1vZF9uYW1lDQogICAgKQ0KICAgIA0KICAgIGVzdF9pIDwtIHRpZHkobW9kX2ksIGVmZmVjdHMgPSAiZml4ZWQiLCBjb25mLmludCA9IFRSVUUpICU+JSANCiAgICAgIGRwbHlyOjpzZWxlY3QodGVybSwgZXN0aW1hdGUsIGNvbmYubG93LCBjb25mLmhpZ2gpICU+JSANCiAgICAgIHRpZHlyOjpwaXZvdF93aWRlcigNCiAgICAgICAgbmFtZXNfZnJvbSA9IHRlcm0sICAgICAgICAgICAgICAgICMgVXNlIGB0ZXJtYCBhcyBjb2x1bW4gbmFtZXMNCiAgICAgICAgdmFsdWVzX2Zyb20gPSBjKGVzdGltYXRlLCBjb25mLmxvdywgY29uZi5oaWdoKSwgICMgVmFsdWVzIHRvIHBpdm90DQogICAgICAgIG5hbWVzX3NlcCA9ICJfIiAgICAgICAgICAgICAgICAgICAjIEFkZCBhIHNlcGFyYXRvciB0byBjb2x1bW4gbmFtZXMNCiAgICAgICkNCiAgICANCiAgICBkZl9pIDwtIGNiaW5kKGRmX2ksIGVzdF9pKQ0KICAgIA0KICAgICMgU3RvcmUgdGhlIGRhdGEgZnJhbWUgaW4gdGhlIGxpc3QNCiAgICBsb29fcmVzdWx0c19saXN0W1ttb2RfbmFtZV1dIDwtIGRmX2kNCiAgfQ0KICANCiAgIyBDb21iaW5kIA0KICBsb29fcmVzdWx0c19jb21iaW5lZCA8LSBiaW5kX3Jvd3MobG9vX3Jlc3VsdHNfbGlzdCkNCiAgDQogICMgR2V0IFIyIA0KICByMl9yZXN1bHRzIDwtIG1hcF9kZnIobW9kZWxzLCB+IGFzLmRhdGEuZnJhbWUoYmF5ZXNfUjIoLngpKSwgLmlkID0gIm1vZGVsIikgJT4lDQogICAgdGliYmxlOjpyZW1vdmVfcm93bmFtZXMoKQ0KICANCiAgIyBDb21iaW5kIFIyIGFuZCBsb28gcmVzdWx0cyANCiAgbW9kZWxfZml0X2RmIDwtIGRwbHlyOjpmdWxsX2pvaW4obG9vX3Jlc3VsdHNfY29tYmluZWQsIHIyX3Jlc3VsdHMsIGJ5ID0gIm1vZGVsIikgJT4lIA0KICAgIGRwbHlyOjpzZWxlY3QobW9kZWwsIGV2ZXJ5dGhpbmcoKSkgJT4lIA0KICAgIGRwbHlyOjpyZW5hbWUocjIgPSBFc3RpbWF0ZSwNCiAgICAgICAgICAgICAgICAgIHIyX2Vycm9yID0gRXN0LkVycm9yLA0KICAgICAgICAgICAgICAgICAgcjJfcTIuNSA9IFEyLjUsDQogICAgICAgICAgICAgICAgICByMl9xOTcuNSA9IFE5Ny41KSAlPiUgDQogICAgZHBseXI6Om11dGF0ZShpZCA9IHN1YigiXyhsbV9cXGQrKSQiLCAiIiwgbW9kZWwpLA0KICAgICAgICAgICAgICAgICAgbW9kZWxfdHlwZSA9IHN1YigiXi4qXyhsbV9cXGQrKSQiLCAiXFwxIiwgbW9kZWwpKQ0KICANCiAgcmV0dXJuKG1vZGVsX2ZpdF9kZikNCn0NCmBgYA0KDQpgYmF5ZXNfbW9kX3ByZWRpY3Rpb25zKClgOiBUaGlzIGZ1bmN0aW9uIGV4dHJhY3RzIHRoZSBwcmVkaWN0ZWQgdmFsdWVzIHVzaW5nIGBmaXR0ZWQoKWAgZnJvbSBhIGxpc3Qgb2YgbW9kZWxzIGFuZCBjb21iaW5lcyB0aGVtIHdpdGggdGhlIG9yaWdpbmFsIGRhdGEgZmlsZSB1c2VkIGZvciB0aGUgbW9kZWwuIFRoZXNlIGFyZSB0aGUgKipwb3N0ZXJpb3IgbWVhbiBmaXR0ZWQgdmFsdWVzKiogKGkuZS4gdGhlIGV4cGVjdGVkIHZhbHVlIG9mIHRoZSByZXNwb25zZSB2YXJpYWJsZSBnaXZlbiB0aGUgcHJlZGljdG9yIHZhcmlhYmxlcyBhbmQgdGhlIGVzdGltYXRlZCBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9ucyBvZiB0aGUgcGFyYW1ldGVycykgZm9yIGVhY2ggb2JzZXJ2YXRpb24gaW4gdGhlIGRhdGFzZXQsIGFsb25nIHdpdGggKio5NSUgY3JlZGlibGUgaW50ZXJ2YWxzKiouDQoNCmBgYHtyfQ0KYmF5ZXNfbW9kX3ByZWRpY3Rpb25zIDwtIGZ1bmN0aW9uKG1vZGVscywgb3JpZ2luYWxfZGF0YSkgew0KICANCiAgcHJlZGljdGlvbl9saXN0IDwtIGxpc3QoKQ0KICANCiAgZm9yIChtb2RfbmFtZSBpbiBuYW1lcyhtb2RlbHMpKSB7DQogICAgIyBFeHRyYWN0IG1vZA0KICAgIG1vZF9pIDwtIG1vZGVsc1tbbW9kX25hbWVdXQ0KICAgIA0KICAgICMgTWFrZSBtb2RlIHByZWRpY3Rpb25zDQogICAgbW9kZWxfcHJlZGljdGlvbnNfaSA8LSBhcy5kYXRhLmZyYW1lKGZpdHRlZChtb2RfaSwgc3VtbWFyeSA9IFRSVUUpKSAlPiUgDQogICAgICBkcGx5cjo6bXV0YXRlKG1vZGVsID0gbW9kX25hbWUsDQogICAgICAgICAgICAgICAgICAgIGlkID0gc3ViKCJfKGxtX1xcZCspJCIsICIiLCBtb2RfbmFtZSksDQogICAgICAgICAgICAgICAgICAgIG1vZGVsX3R5cGUgPSBzdWIoIl4uKl8obG1fXFxkKykkIiwgIlxcMSIsIG1vZF9uYW1lKSkgJT4lIA0KICAgICAgZHBseXI6OnJlbmFtZShwcmVkX2xvd2VyID0gUTIuNSwgcHJlZF91cHBlciA9IFE5Ny41LCBwcmVkaWN0ZWQgPSBFc3RpbWF0ZSwgcHJlZF9lcnJvciA9IEVzdC5FcnJvcikgJT4lIA0KICAgICAgZHBseXI6OnNlbGVjdChtb2RlbCwgZXZlcnl0aGluZygpKQ0KICAgIA0KICAgIGlkX2kgPC0gbW9kZWxfcHJlZGljdGlvbnNfaSRpZFsxXQ0KICAgIA0KICAgIG9yaWdpbmFsX2RhdGFfaSA8LSBvcmlnaW5hbF9kYXRhICU+JSANCiAgICAgIGRwbHlyOjpmaWx0ZXIoaWQgPT0gaWRfaSkgJT4lIA0KICAgICAgZHBseXI6OnNlbGVjdCgtaWQpDQogICAgDQogICAgbW9kZWxfcHJlZGljdGlvbnNfb3JpZ2luYWxfaSA8LSBjYmluZChtb2RlbF9wcmVkaWN0aW9uc19pLCBvcmlnaW5hbF9kYXRhX2kpDQogICAgDQogICAgcHJlZGljdGlvbl9saXN0W1ttb2RfbmFtZV1dIDwtIG1vZGVsX3ByZWRpY3Rpb25zX29yaWdpbmFsX2kNCiAgfQ0KICBwcmVkaWN0aW9uc19kZiA8LSBiaW5kX3Jvd3MocHJlZGljdGlvbl9saXN0KSANCiAgcmV0dXJuKHByZWRpY3Rpb25zX2RmKQ0KfQ0KYGBgDQoNCmBjYWxjU01SKClgOiAqKmF1dGhvcmVkIGJ5IERlbmlzIENoYWJvdCoqIHVzZWQgdG8gZXN0aW1hdGUgU01SIHdpdGggc2V2ZXJhbCBkaWZmZXJlbnQgbWV0aG9kcyBDbGFpcmVhdXggYW5kIENoYWJvdCAoMjAxNikgXlsxXV4NCg0KXlsxXV4gQ2xhaXJlYXV4LCBHLiBhbmQgQ2hhYm90LCBELiAoMjAxNikgUmVzcG9uc2VzIGJ5IGZpc2hlcyB0byBlbnZpcm9ubWVudGFsIGh5cG94aWE6IGludGVncmF0aW9uIHRocm91Z2ggRnJ5J3MgY29uY2VwdCBvZiBhZXJvYmljIG1ldGFib2xpYyBzY29wZS4gSm91cm5hbCBvZiBGaXNoIEJpb2xvZ3kgPGh0dHBzOi8vZG9pLm9yZy8xMC4xMTExL2pmYi4xMjgzMz4NCg0KYGBge3J9DQpjYWxjU01SID0gZnVuY3Rpb24oWSwgcT1jKDAuMSwwLjE1LDAuMiwwLjI1LDAuMyksIEc9MTo0KXsNCgl1ID0gc29ydChZKQ0KCXRoZS5NY2x1c3QgPC0gTWNsdXN0KFksICBHPUcpDQoJY2wgPC0gdGhlLk1jbHVzdCRjbGFzc2lmaWNhdGlvbg0KCSMgc29tZXRpbWVzLCB0aGUgY2xhc3MgY29udGFpbmluZyBTTVIgaXMgbm90IGNhbGxlZCAxDQoJIyB0aGUgZm9sbG93aW5nIHByZXN1bWVzIHRoYXQgd2hlbiBjbGFzcyAxIGNvbnRhaW5zID4gMTAlIG9mIGNhc2VzLCANCgkjIGl0IGNvbnRhaW5zIFNNUiwgb3RoZXJ3aXNlIHdlIHRha2UgY2xhc3MgMg0KCWNsMiA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKGNsKSkNCgljbDIkY2wgPC0gYXMubnVtZXJpYyhsZXZlbHMoY2wyJGNsKSkNCgl2YWxpZCA8LSBjbDIkRnJlcT49MC4xKmxlbmd0aCh0aW1lKSAgDQoJdGhlLmNsIDwtIG1pbihjbDIkY2xbdmFsaWRdKQ0KCWxlZnQuZGlzdHIgPC0gWVt0aGUuTWNsdXN0JGNsYXNzaWZpY2F0aW9uPT10aGUuY2xdDQoJbWxuZCA9IHRoZS5NY2x1c3QkcGFyYW1ldGVycyRtZWFuW3RoZS5jbF0NCglDVm1sbmQgPSBzZChsZWZ0LmRpc3RyKS9tbG5kICogMTAwDQoJcXVhbnQ9cXVhbnRpbGUoWSwgcSkNCglsb3cxMD1tZWFuKHVbMToxMF0pDQoJbG93MTBwYyA9IG1lYW4odVs2Oig1ICsgcm91bmQoMC4xKihsZW5ndGgodSktNSkpKV0pDQoJIyByZW1vdmUgNSBvdXRsaWVycywga2VlcCBsb3dlc3QgMTAlIG9mIHRoZSByZXN0LCBhdmVyYWdlDQoJIyBIZXJybWFubiAmIEVuZGVycyAyMDAwDQoJcmV0dXJuKGxpc3QobWxuZD1tbG5kLCBxdWFudD1xdWFudCwgbG93MTA9bG93MTAsIGxvdzEwcGM9bG93MTBwYywNCgkJICAgICAgY2w9Y2wsIENWbWxuZD1DVm1sbmQpKQ0KfQ0KYGBgDQoNCmBjYWxjTzJjcml0KClgOiAqKmF1dGhvcmVkIGJ5IERlbmlzIENoYWJvdCoqIHVzZWQgdG8gZXN0aW1hdGUgTzJjcml0IChQY3JpcHQpLiBDbGFpcmVhdXggYW5kIENoYWJvdCAoMjAxNikgXlsxXV4NCg0KKioqTm90ZTogTzIgaXMgYXNzdW1lZCB0byBiZSBpbiBwZXJjZW50YWdlIG9mIGRpc3NvbHZlZCBveHlnZW4gKERPKSoqKg0KDQpgYGB7cn0NCmNhbGNPMmNyaXQgPC0gZnVuY3Rpb24oRGF0YSwgU01SLCBsb3dlc3RNTzIgPSBOQSwgZ2FwTGltaXQgPSA0LA0KbWF4Lm5iLk1PMi5mb3IucmVnID0gMjApDQp7DQojIEFVVEhPUjogRGVuaXMgQ2hhYm90LCBJbnN0aXR1dCBNYXVyaWNlLUxhbW9udGFnbmUsIERGTywgQ2FuYWRhDQojIGZpcnN0IHZlcnNpb24gd3JpdHRlbiBpbiBKdW5lIDIwMDkNCiMgbGFzdCB1cGRhdGVkIGluIEphbnVhcnkgMjAxNQ0KbWV0aG9kID0gIkxTX3JlZyIgIyB3aWxsIGJlY29tZSAidGhyb3VnaF9vcmlnaW4iIGlmIGludGVyY2VwdCBpcyA+IDANCmlmKGlzLm5hKGxvd2VzdE1PMikpIGxvd2VzdE1PMiA9IHF1YW50aWxlKERhdGEkTU8yW0RhdGEkRE8gPj0gODBdLCBwPTAuMDUpDQojIFN0ZXAgMTogaWRlbnRpZnkgcG9pbnRzIHdoZXJlIE1PMiBpcyBwcm9wb3J0aW9uYWwgdG8gRE8NCmdlcVNNUiA9IERhdGEkTU8yID49IGxvd2VzdE1PMg0KcGl2b3RETyA9IG1pbihEYXRhJERPW2dlcVNNUl0pDQpsZXRoYWwgPSBEYXRhJERPIDwgcGl2b3RETw0KTl91bmRlcl9TTVIgPSBzdW0obGV0aGFsKSAjIHBvaW50cyBhdmFpbGFibGUgZm9yIHJlZ3Jlc3Npb24/DQpmaW5hbF9OX3VuZGVyX1NNUiA9IGxldGhhbCAjIHNvbWUgcG9pbnRzIG1heSBiZSByZW1vdmVkIGF0IFN0ZXAgNA0KbGFzdE1PMnJlZyA9IERhdGEkTU8yW0RhdGEkRE8gPT0gcGl2b3RET10gIyBsYXN0IE1PMiB3aGVuIHJlZ3VsYXRpbmcNCmlmKE5fdW5kZXJfU01SID4gMSkgdGhlTW9kID0gbG0oTU8yfkRPLCBkYXRhPURhdGFbbGV0aGFsLF0pDQojIFN0ZXAgMiwgYWRkIG9uZSBvciBtb3JlIHBvaW50IGF0IG9yIGFib3ZlIFNNUg0KIyAyQSwgd2hlbiB0aGVyZSBhcmUgZmV3ZXIgdGhhbiAzIHZhbGlkIHBvaW50cyB0byBjYWxjdWxhdGUgYSByZWdyZXNzaW9uDQppZihOX3VuZGVyX1NNUiA8IDMpew0KbWlzc2luZyA9IDMgLSBzdW0obGV0aGFsKQ0Kbm90LmxldGhhbCA9IERhdGEkRE9bZ2VxU01SXQ0KRE9saW1pdCA9IG1heChzb3J0KG5vdC5sZXRoYWwpWzE6bWlzc2luZ10pICMgaGlnaGVzdCBETyBhY2NlcHRhYmxlDQojIHRvIHJlYWNoIGEgTiBvZiAzDQphZGRlZFBvaW50cyA9IERhdGEkRE8gPD0gRE9saW1pdA0KbGV0aGFsID0gbGV0aGFsIHwgYWRkZWRQb2ludHMNCnRoZU1vZCA9IGxtKE1PMn5ETywgZGF0YT1EYXRhW2xldGhhbCxdKQ0KfQ0KIyAyQiwgYWRkIHBpdm90RE8gdG8gdGhlIGZpdCB3aGVuIFN0ZXAgMSB5aWVsZGVkIDMgb3IgbW9yZSB2YWx1ZXM/DQppZihOX3VuZGVyX1NNUiA+PSAzKXsNCmxldGhhbEIgPSBEYXRhJERPIDw9IHBpdm90RE8gIyBoYXMgb25lIG1vcmUgdmFsdWUgdGhhbiAibGV0aGFsIg0KcmVnQSA9IHRoZU1vZA0KcmVnQiA9IGxtKE1PMn5ETywgZGF0YT1EYXRhW2xldGhhbEIsXSkNCmxhcmdlX3Nsb3BlX2Ryb3AgPSAoY29lZihyZWdBKVsyXS9jb2VmKHJlZ0IpWzJdKSA+IDEuMSAjIGFyYml0cmFyeQ0KbGFyZ2VfRE9fZ2FwID0gKG1heChEYXRhJERPW2xldGhhbEJdKSAtIG1heChEYXRhJERPW2xldGhhbF0pKSA+IGdhcExpbWl0DQp0b29TbWFsbE1PMiA9IGxhc3RNTzJyZWcgPCBTTVINCmlmKCFsYXJnZV9zbG9wZV9kcm9wICYgIWxhcmdlX0RPX2dhcCAmICF0b29TbWFsbE1PMikgew0KbGV0aGFsID0gbGV0aGFsQg0KdGhlTW9kID0gcmVnQg0KfSAjIG90aGVyd2lzZSB3ZSBkbyBub3QgYWNjZXB0IHRoZSBhZGRpdGlvbmFsIHBvaW50DQp9DQojIFN0ZXAgMw0KIyBpZiB0aGUgdXNlciB3YW50cyB0byBsaW1pdCB0aGUgbnVtYmVyIG9mIHBvaW50cyBpbiB0aGUgcmVncmVzc2lvbg0KaWYoIWlzLm5hKG1heC5uYi5NTzIuZm9yLnJlZykgJiBzdW0obGV0aGFsKT5tYXgubmIuTU8yLmZvci5yZWcpew0KUmFua3MgPSByYW5rKERhdGEkRE8pDQpsZXRoYWwgPSBSYW5rcyA8PSBtYXgubmIuTU8yLmZvci5yZWcNCnRoZU1vZCA9IGxtKE1PMn5ETywgZGF0YT1EYXRhW2xldGhhbCxdKQ0KZmluYWxfTl91bmRlcl9TTVIgPSBtYXgubmIuTU8yLmZvci5yZWcNCn0NCiMgU3RlcCA0DQpwcmVkTU8yID0gYXMubnVtZXJpYyhwcmVkaWN0KHRoZU1vZCwgZGF0YS5mcmFtZShETz1EYXRhJERPKSkpDQpEYXRhJGRlbHRhID0gKERhdGEkTU8yLXByZWRNTzIpL3ByZWRNTzIgKiAxMDAgIyByZXNpZHVhbHMgc2V0IHRvIHplcm8NCiMgd2hlbiBiZWxvdyBwaXZvdERPDQpEYXRhJGRlbHRhW0RhdGEkRE8gPCBwaXZvdERPIHwgbGV0aGFsXSA9IDANCnRvbCA9IDAgIyBhbnkgcG9zaXRpdmUgcmVzaWR1YWwgaXMgdW5hY2NlcHRhYmxlDQpIaWdoVmFsdWVzID0gRGF0YSRkZWx0YSA+IHRvbA0KUmFua3MgPSByYW5rKC0xKkRhdGEkZGVsdGEpDQpIaWdoTU8yID0gSGlnaFZhbHVlcyAmIFJhbmtzID09IG1pbihSYW5rcykgIyBrZWVwIGxhcmdlc3QgcmVzaWR1YWwNCmlmIChzdW0oSGlnaFZhbHVlcykgPiAwKSB7DQpuYmxldGhhbCA9IHN1bShsZXRoYWwpDQpEYXRhJFcgPSBOQQ0KRGF0YSRXW2xldGhhbF09MS9uYmxldGhhbA0KRGF0YSRXW0hpZ2hNTzJdID0gMQ0KdGhlTW9kID0gbG0oTU8yfkRPLCB3ZWlnaHQ9VywgZGF0YT1EYXRhW2xldGhhbCB8IEhpZ2hNTzIsXSkNCiMgVGhpcyBuZXcgcmVncmVzc2lvbiBpcyBhbHdheXMgYW4gaW1wcm92ZW1lbnQsIGJ1dCB0aGVyZSBjYW4gc3RpbGwNCiMgYmUgcG9pbnRzIGFib3ZlIHRoZSBsaW5lLCBzbyB3ZSByZXBlYXQNCnByZWRNTzJfMiA9IGFzLm51bWVyaWMocHJlZGljdCh0aGVNb2QsIGRhdGEuZnJhbWUoRE89RGF0YSRETykpKQ0KRGF0YSRkZWx0YTIgPSAoRGF0YSRNTzItcHJlZE1PMl8yKS9wcmVkTU8yXzIgKiAxMDANCkRhdGEkZGVsdGEyW0RhdGEkRE8gPCBwaXZvdERPXSA9IDANCnRvbCA9IERhdGEkZGVsdGEyW0hpZ2hNTzJdDQpIaWdoVmFsdWVzMiA9IERhdGEkZGVsdGEyID4gdG9sDQppZihzdW0oSGlnaFZhbHVlczIpPjApew0KUmFua3MyID0gcmFuaygtMSpEYXRhJGRlbHRhMikNCkhpZ2hNTzJfMiA9IEhpZ2hWYWx1ZXMyICYgUmFua3MyID09IDEgIyBrZWVwIHRoZSBsYXJnZXN0IHJlc2lkdWFsDQpuYmxldGhhbCA9IHN1bShsZXRoYWwpDQpEYXRhJFcgPSBOQQ0KRGF0YSRXW2xldGhhbF09MS9uYmxldGhhbA0KRGF0YSRXW0hpZ2hNTzJfMl0gPSAxDQp0aGVNb2QyID0gbG0oTU8yfkRPLCB3ZWlnaHQ9VywgZGF0YT1EYXRhW2xldGhhbCB8IEhpZ2hNTzJfMixdKQ0KIyBpcyBuZXcgc2xvcGUgc3RlZXBlciB0aGFuIHRoZSBvbGQgb25lPw0KaWYodGhlTW9kMiRjb2VmWzJdID4gdGhlTW9kJGNvZWZbMl0pIHsNCnRoZU1vZCA9IHRoZU1vZDINCkhpZ2hNTzIgPSBIaWdoTU8yXzINCn0NCn0gIyBlbmQgc2Vjb25kIHNlYXJjaCBmb3IgaGlnaCB2YWx1ZQ0KfSAjIGVuZCBmaXJzdCBzZWFyY2ggZm9yIGhpZ2ggdmFsdWUNCkNvZWYgPSBjb2VmZmljaWVudHModGhlTW9kKQ0KI1N0ZXAgNSwgY2hlY2sgZm9yIHBvc2l0aXZlIGludGVyY2VwdA0KQWJvdmVPcmlnaW4gPSBDb2VmWzFdID4gMA0KIyBpZiBpdCBpcywgd2UgdXNlIGEgcmVncmVzc2lvbiB0aGF0IGdvZXMgdGhyb3VnaCB0aGUgb3JpZ2luDQppZiAoQWJvdmVPcmlnaW4pew0KdGhlTW9kID0gbG0oTU8yfkRPIC0xLCBkYXRhPURhdGFbbGV0aGFsLF0pDQpDb2VmID0gYygwLCBjb2VmZmljaWVudHModGhlTW9kKSkgIyBuZWVkIHRvIGFkZCB0aGUgaW50ZXJjZXB0ICgwKQ0KIyBtYW51YWxseSB0byBoYXZlIGEgcGFpciBvZiBjb2VmZmljaWVudHMNCm1ldGhvZCA9ICJ0aHJvdWdoX29yaWdpbiINCkhpZ2hNTzIgPSByZXAoRkFMU0UsIG5yb3coRGF0YSkpICMgZGlkIG5vdCB1c2UgdGhlIGFkZGl0aW9uYWwgdmFsdWUNCiMgZnJvbSBTdGVwIDQNCn0NCnBvMmNyaXQgPSBhcy5udW1lcmljKHJvdW5kKChTTVIgLSBDb2VmWzFdKSAvIENvZWZbMl0sIDEpKQ0Kc3VtX21vZCA9IHN1bW1hcnkodGhlTW9kKQ0KYW5vdl9tb2QgPSBhbm92YSh0aGVNb2QpDQpPMkNSSVQgPSBsaXN0KG8yY3JpdD1wbzJjcml0LCBTTVI9U01SLCBOYl9NTzJfY29uZm9ybWluZyA9IE5fdW5kZXJfU01SLA0KTmJfTU8yX2NvbmZfdXNlZCA9IGZpbmFsX05fdW5kZXJfU01SLA0KSGlnaF9NTzJfcmVxdWlyZWQgPSBzdW0oSGlnaE1PMikgPT0gMSwgb3JpZ0RhdGE9RGF0YSwNCk1ldGhvZD1tZXRob2QsIG1vZD10aGVNb2QsIHIyID0gc3VtX21vZCRyLnNxdWFyZWQsDQpQID0gYW5vdl9tb2QkIlByKD5GKSIsIGxldGhhbFBvaW50cyA9IHdoaWNoKGxldGhhbCksDQpBZGRlZFBvaW50cyA9IHdoaWNoKEhpZ2hNTzIpKQ0KfSAjIGVuZCBmdW5jdGlvbg0KYGBgDQoNCmBwbG90TzJjcml0KClgOiAqKmF1dGhvcmVkIGJ5IERlbmlzIENoYWJvdCoqLCB1c2VkIHRvIHBsb3QgdGhlIG1vZGVzIHVzZWQgZm9yIHRoZSBgY2FsY08yY3JpdCgpYCBmdW5jdGlvbi4gQ2xhaXJlYXV4IGFuZCBDaGFib3QgKDIwMTYpIF5bMV1eDQoNCioqKk5vdGU6IEkgYWRkZWQgYWJsaW5lKGg9bG93ZXN0TU8yLCBjb2w9InBpbmsiKSBzbyB0aGF0IEkgY291bGQgdmlzdWFsaXNlIHRoZSBsb3dlc3RNTzIgcG9zaXRpb24qKioNCg0KYGBge3J9DQpwbG90TzJjcml0IDwtIGZ1bmN0aW9uKG8yY3JpdG9iaiwgcGxvdElEPSIiLA0KWGxhYj0iRGlzc29sdmVkIG94eWdlbiAoJSBzYXQuKSIsIFlsYWI9ImRvdGl0YWx1bW9sIiwNCnNtci5jZXg9MC45LCBvMmNyaXQuY2V4PTAuOSwgcGxvdElELmNleD0xLjIsDQpUcmFuc3BhcmVuY3k9VCwuLi4pDQp7DQojIEFVVEhPUjogRGVuaXMgQ2hhYm90LCBJbnN0aXR1dCBNYXVyaWNlLUxhbW9udGFnbmUsIERGTywgQ2FuYWRhDQojIGZpcnN0IHZlcnNpb24gd3JpdHRlbiBpbiBKdW5lIDIwMDkNCiMgbGFzdCB1cGRhdGVkIDIwMTUtMDItMDkNCiMgZm9yIFIgcGxvdHRpbmcgZGV2aWNlcyB0aGF0IGRvIG5vdCBzdXBwb3J0IHRyYW5zcGFyZW5jeQ0KIyAoZS5nLiwgcG9zdHNjcmlwdCksIHNldCBUcmFuc3BhcmVuY3kgdG8gRkFMU0UNCnNtciA9IG8yY3JpdG9iaiRTTVINCmlmKFlsYWIgJWluJSBjKCJkb3RpdGFsdW1vbCIsICJpdGFsdW1vbCIsICJkb3R1bW9sIiwgInVtb2wiLA0KImRvdGl0YWxtZyIsICJpdGFsbWciLCAiZG90bWciLCAibWciKSkgew0Kc3dpdGNoKFlsYWIsDQpkb3RpdGFsdW1vbCA9IHsNCm1vMi5sYWIgPSBleHByZXNzaW9uKHBhc3RlKGl0YWxpYyhkb3QoTSkpW09bMl1dLCAiICgiLG11LCJtb2wgIiwgT1syXSwNCiIgIiwgbWluXi0xLCAiICIsIGtnXi0xLCAiKSIpKQ0KfSwNCml0YWx1bW9sID0gew0KbW8yLmxhYiA9IGV4cHJlc3Npb24ocGFzdGUoaXRhbGljKE0pW09bMl1dLCAiICgiLG11LCJtb2wgIiwgT1syXSwgIiAiLA0KbWluXi0xLCAiICIsIGtnXi0xLCAiKSIpKQ0KfSwNCmRvdHVtb2wgPSB7DQptbzIubGFiID0gZXhwcmVzc2lvbihwYXN0ZShkb3QoTSlbT1syXV0sICIgKCIsbXUsIm1vbCAiLCBPWzJdLCAiICIsDQptaW5eLTEsICIgIiwga2deLTEsICIpIikpDQp9LA0KdW1vbCA9IHsNCm1vMi5sYWIgPSBleHByZXNzaW9uKHBhc3RlKE1bT1syXV0sICIgKCIsbXUsIm1vbCAiLCBPWzJdLCAiICIsIG1pbl4tMSwNCiIgIiwga2deLTEsICIpIikpDQp9LA0KZG90aXRhbG1nID0gew0KbW8yLmxhYiA9IGV4cHJlc3Npb24ocGFzdGUoaXRhbGljKGRvdChNKSlbT1syXV0sICIgKG1nICIsIE9bMl0sICIgIiwNCmheLTEsICIgIiwga2deLTEsICIpIikpDQp9LA0KaXRhbG1nID0gew0KbW8yLmxhYiA9IGV4cHJlc3Npb24ocGFzdGUoaXRhbGljKE0pW09bMl1dLCAiIChtZyAiLCBPWzJdLCAiICIsDQpoXi0xLCAiICIsIGtnXi0xLCAiKSIpKQ0KfSwNCmRvdG1nID0gew0KbW8yLmxhYiA9IGV4cHJlc3Npb24ocGFzdGUoZG90KE0pW09bMl1dLCAiIChtZyAiLCBPWzJdLCAiICIsIGheLTEsICIgIiwNCmtnXi0xLCAiKSIpKQ0KfSwNCm1nID0gew0KbW8yLmxhYiA9IGV4cHJlc3Npb24ocGFzdGUoTVtPWzJdXSwgIiAobWcgIiwgT1syXSwgIiAiLCBoXi0xLCAiICIsDQprZ14tMSwgIikiKSkNCn0NCikNCn0gZWxzZSBtbzIubGFiPVlsYWINCmlmKFRyYW5zcGFyZW5jeSkge0NvbD1jKHJnYigwLDAsMCwwLjcpLCAicmVkIiwgIm9yYW5nZSIpDQp9IGVsc2Uge0NvbD1jKGdyZXkoMC4zKSwgInJlZCIsICJvcmFuZ2UiKX0NCkRhdGE9bzJjcml0b2JqJG9yaWdEYXRhDQpsb3dlc3RNTzIgPSBxdWFudGlsZShEYXRhJE1PMltEYXRhJERPID49IDgwXSwgcD0wLjA1KSAjIEkgYWRkZWQgdGhpcw0KRGF0YSRDb2xvciA9IENvbFsxXQ0KRGF0YSRDb2xvcltvMmNyaXRvYmokbGV0aGFsUG9pbnRzXSA9IENvbFsyXQ0KRGF0YSRDb2xvcltvMmNyaXRvYmokQWRkZWRQb2ludHNdID0gQ29sWzNdDQojIG9yZGluYXJ5IExTIHJlZ3Jlc3Npb24gd2l0aG91dCBhZGRlZCBwb2ludHM6IGJsdWUgbGluZSwgcmVkIHN5bWJvbHMNCiMgb3JkaW5hcnkgTFMgcmVncmVzc2lvbiB3aXRoIGFkZGVkIHBvaW50czogYmx1ZSBsaW5lLCByZWQgJiBvcmFuZ2Ugc3ltYm9scw0KIyByZWdyZXNzaW9uIHRocm91Z2ggb3JpZ2luOiBncmVlbiBkb3R0ZWQgbGluZSwgcmVkIHN5bWJvbHMNCmxpbmUuY29sb3IgPSBpZmVsc2UobzJjcml0b2JqJE1ldGhvZD09IkxTX3JlZyIsICJibHVlIiwgImRhcmtncmVlbiIpDQpsaW5lLnR5cGUgPSBpZmVsc2UobzJjcml0b2JqJE1ldGhvZD09IkxTX3JlZyIsIDEsIDMpDQpsaW1YID0gYygwLCBtYXgoRGF0YSRETykpDQpsaW1ZID0gYygwLCBtYXgoRGF0YSRNTzIpKQ0KcGxvdChNTzJ+RE8sIGRhdGE9RGF0YSwgeGxpbT1saW1YLCB5bGltPWxpbVksIGNvbD1EYXRhJENvbG9yLCB4bGFiPVhsYWIsDQp5bGFiPW1vMi5sYWIsIC4uLikNCmNvb3JkIDwtIHBhcigidXNyIikNCmlmKHBsb3RJRCAhPSAiIil7DQp0ZXh0KDAsIGNvb3JkWzRdLCBwbG90SUQsIGNleD1wbG90SUQuY2V4LCBhZGo9YygwLDEuMikpDQp9DQphYmxpbmUoaD1sb3dlc3RNTzIsIGNvbD0icGluayIpICMgSSBhZGRlZCB0aGlzDQphYmxpbmUoaD1zbXIsIGNvbD0ib3JhbmdlIikNCnRleHQoY29vcmRbMV0sIHNtciwgIlNNUiIsIGFkaj1jKC0wLjEsMS4zKSwgY2V4PXNtci5jZXgpDQp0ZXh0KGNvb3JkWzFdLCBzbXIsIHJvdW5kKHNtciwxKSwgYWRqPWMoLTAuMSwtMC4zKSwgY2V4PXNtci5jZXgpDQppZighaXMubmEobzJjcml0b2JqJG8yY3JpdCkpIHsNCmFibGluZShvMmNyaXRvYmokbW9kLCBjb2w9bGluZS5jb2xvciwgbHR5PWxpbmUudHlwZSkNCnNlZ21lbnRzKG8yY3JpdG9iaiRvMmNyaXQsIHNtciwgbzJjcml0b2JqJG8yY3JpdCwgY29vcmRbM10sDQpjb2w9bGluZS5jb2xvciwgbHdkPTEpDQp0ZXh0KHg9bzJjcml0b2JqJG8yY3JpdCwgeT0wLCBvMmNyaXRvYmokbzJjcml0LCBjb2w9bGluZS5jb2xvciwNCmNleD1vMmNyaXQuY2V4LCBhZGo9YygtMC4xLDAuNSkpDQp9DQp9ICMgZW5kIG9mIGZ1bmN0aW9uDQpgYGANCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQojIPCfk4IgRGlyZWN0b3JpZXMNCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQojIyBJbnB1dA0KDQoqKvCfk6UgaW5wdXRfZGF0YV93ZCoqOiBEaXJlY3RvcnkgZm9yIHRoZSBtZXRhZGF0YQ0KDQpgYGB7cn0NCndkIDwtIGdldHdkKCkNCmlucHV0X2RhdGFfd2QgPC0gcGFzdGUwKHdkLCAiLi9pbnB1dC1kYXRhIikgIyBjcmVhdGVzIGEgdmFyaWFibGUgd2l0aCB0aGUgbmFtZSBvZiB0aGUgd2Qgd2Ugd2FudCB0byB1c2UNCmBgYA0KDQoqKvCfk6UgbW9kX2RhdGFfd2QqKjogRGlyZWN0b3J5IGZvciBtb2RlbCBvdXRwdXQgZGF0YSBlc3RpbWF0ZWQgc2xvcGVzDQoNCmBgYHtyfQ0KbW9kX2RhdGFfd2QgPC0gcGFzdGUwKHdkLCAiLi9tb2QtZGF0YSIpDQpgYGANCg0KIyMgT3V0cHV0DQoNCioq8J+TpCBvdXRwdXRfZmlnX3dkKio6IHRoaXMgaXMgd2hlcmUgd2Ugd2lsbCBwdXQgdGhlIGZpZ3VyZXMNCg0KYGBge3J9DQpvdXRwdXRfZmlnX3dkIDwtIHBhc3RlMCh3ZCwgIi4vb3V0cHV0LWZpZyIpDQppZiAoIWRpci5leGlzdHMoIm91dHB1dC1maWciKSkge2Rpci5jcmVhdGUoIm91dHB1dC1maWciKX0NCmBgYA0KDQoqKvCfk6Qgb3V0cHV0X21vZHNfd2QqKjogdGhpcyBpcyB3aGVyZSB3ZSB3aWxsIHB1dCB0aGUgbW9kZWxzDQoNCmBgYHtyfQ0Kb3V0cHV0X21vZHNfd2QgPC0gcGFzdGUwKHdkLCAiLi9vdXRwdXQtbW9kIikNCmlmICghZGlyLmV4aXN0cygib3V0cHV0LW1vZCIpKSB7ZGlyLmNyZWF0ZSgib3V0cHV0LW1vZCIpfQ0KYGBgDQoNCjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT4NCg0KIyDwn5K/IERhdGENCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQojIyBTbG9wZXMgKOG5gE8pDQoNCioq8J+SvyBzbG9wZV9kZioqOiBXZSBoYXZlIGltcG9ydGVkIHRoZSBzbG9wZXMgZXh0cmFjdGVkIGluIExhYkNoYXJ0IGR1cmluZyBlYWNoIHBoYXNlIG9mIHRoZSBleHBlcmltZW50DQoNCmBgYHtyfQ0KIHNldHdkKGlucHV0X2RhdGFfd2QpDQoNCmRhdGFfZmlsZSA8LSAibGFiY2hhcnQtc2xvcGUtZGF0YS54bHN4Ig0KDQojIA0KIyAjIEdldCB0aGUgbmFtZXMgb2YgYWxsIHNoZWV0cyBpbiB0aGUgRXhjZWwgZmlsZQ0Kc2hlZXRfbmFtZXMgPC0gcmVhZHhsOjpleGNlbF9zaGVldHMoZGF0YV9maWxlKQ0KYWxsX3RyaWFsc19zZWxlY3QgPC0gYygic3RhcnRfZGF0ZSIsICJvcmRlciIsICJwaGFzZSIsICJjeWNsZSIsICJkYXRlIiwgInRpbWUiKQ0Kc2xvcGVfbGlzdCA8LSBsaXN0KCkNCg0KZm9yIChzaGVldCBpbiBzaGVldF9uYW1lcykgew0KDQogIGRmIDwtIHJlYWRfZXhjZWwoZGF0YV9maWxlLCBzaGVldCA9IHNoZWV0KSAlPiUgDQogIGRwbHlyOjpyZW5hbWVfd2l0aCh0b2xvd2VyKQ0KICANCmFfbmFtZSA8LSBwYXN0ZTAoImFfIiwgdG9sb3dlcihzaGVldCkpDQphX2RmIDwtIGRmICU+JQ0KICBkcGx5cjo6c2VsZWN0KHN0YXJ0c193aXRoKCdhJyksIGFsbF90cmlhbHNfc2VsZWN0KSAlPiUgDQogIGRwbHlyOjpyZW5hbWUodGVtcCA9IGFfdGVtcCkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKGFjcm9zcyhzdGFydHNfd2l0aCgnYScpLCBhcy5udW1lcmljKSkgJT4lIA0KICBwaXZvdF9sb25nZXIoDQogICAgY29scyA9IHN0YXJ0c193aXRoKCdhJyksICMgU2VsZWN0IGFsbCBjb2x1bW5zIHRvIHBpdm90DQogICAgbmFtZXNfdG8gPSBjKCJjaGFtYmVyX2lkIiwgIi52YWx1ZSIpLCAjIFNlcGFyYXRlIGNvbHVtbiBuYW1lcyBpbnRvICdpZCcgYW5kIG90aGVyIHZhcmlhYmxlcw0KICAgIG5hbWVzX3NlcCA9ICJfIg0KICApICU+JQ0KICBkcGx5cjo6bXV0YXRlKHJlc3Bpcm9tZXRlcl9ncm91cCA9ICJhIikgIyBBZGQgYSBuZXcgY29sdW1uIHdpdGggYSBmaXhlZCB2YWx1ZQ0KDQpzbG9wZV9saXN0W1thX25hbWVdXTwtIGFfZGYNCg0KYl9uYW1lIDwtIHBhc3RlMCgiYl8iLCB0b2xvd2VyKHNoZWV0KSkNCmJfZGYgPC0gZGYgJT4lIA0KICBkcGx5cjo6c2VsZWN0KHN0YXJ0c193aXRoKCdiJyksIGFsbF90cmlhbHNfc2VsZWN0KSAlPiUgDQogIGRwbHlyOjpyZW5hbWUodGVtcCA9IGJfdGVtcCkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKGFjcm9zcyhzdGFydHNfd2l0aCgnYicpLCBhcy5udW1lcmljKSkgJT4lIA0KICBwaXZvdF9sb25nZXIoDQogICAgY29scyA9IHN0YXJ0c193aXRoKCdiJyksICMgU2VsZWN0IGFsbCBjb2x1bW5zIHRvIHBpdm90DQogICAgbmFtZXNfdG8gPSBjKCJjaGFtYmVyX2lkIiwgIi52YWx1ZSIpLCAjIFNlcGFyYXRlIGNvbHVtbiBuYW1lcyBpbnRvICdpZCcgYW5kIG90aGVyIHZhcmlhYmxlcw0KICAgIG5hbWVzX3NlcCA9ICJfIg0KICApICU+JSANCiAgICBkcGx5cjo6bXV0YXRlKHJlc3Bpcm9tZXRlcl9ncm91cCA9ICJiIikNCg0Kc2xvcGVfbGlzdFtbYl9uYW1lXV0gPC0gYl9kZg0KDQpjX25hbWUgPC0gcGFzdGUwKCJjXyIsIHRvbG93ZXIoc2hlZXQpKQ0KY19kZiA8LSBkZiAlPiUgDQogIGRwbHlyOjpzZWxlY3Qoc3RhcnRzX3dpdGgoJ2MnKSwgYWxsX3RyaWFsc19zZWxlY3QpICU+JSANCiAgZHBseXI6OnJlbmFtZSh0ZW1wID0gY190ZW1wLA0KICAgICAgICAgICAgICAgIGlfY3ljbGUgPSBjeWNsZSkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKGFjcm9zcyhzdGFydHNfd2l0aCgnYycpLCBhcy5udW1lcmljKSkgJT4lDQogIHBpdm90X2xvbmdlcigNCiAgICBjb2xzID0gc3RhcnRzX3dpdGgoJ2MnKSwgIyBTZWxlY3QgYWxsIGNvbHVtbnMgdG8gcGl2b3QNCiAgICBuYW1lc190byA9IGMoImNoYW1iZXJfaWQiLCAiLnZhbHVlIiksICMgU2VwYXJhdGUgY29sdW1uIG5hbWVzIGludG8gJ2lkJyBhbmQgb3RoZXIgdmFyaWFibGVzDQogICAgbmFtZXNfc2VwID0gIl8iDQogICkgJT4lIA0KICAgIGRwbHlyOjptdXRhdGUocmVzcGlyb21ldGVyX2dyb3VwID0gImMiKSAlPiUgDQogIGRwbHlyOjpyZW5hbWUoY3ljbGUgPSBpX2N5Y2xlKQ0KDQpzbG9wZV9saXN0W1tjX25hbWVdXSA8LSBjX2RmDQoNCmRfbmFtZSA8LSBwYXN0ZTAoImRfIiwgdG9sb3dlcihzaGVldCkpDQpkX2RmIDwtIGRmICU+JSANCiAgZHBseXI6OnNlbGVjdChzdGFydHNfd2l0aCgnZCcpLCBhbGxfdHJpYWxzX3NlbGVjdCkgJT4lIA0KICBkcGx5cjo6cmVuYW1lKHRlbXAgPSBkX3RlbXAsDQogICAgICAgICAgICAgICAgaV9kYXRlID0gZGF0ZSkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKGFjcm9zcyhzdGFydHNfd2l0aCgnZCcpLCBhcy5udW1lcmljKSkgJT4lDQogIHBpdm90X2xvbmdlcigNCiAgICBjb2xzID0gc3RhcnRzX3dpdGgoJ2QnKSwgIyBTZWxlY3QgYWxsIGNvbHVtbnMgdG8gcGl2b3QNCiAgICBuYW1lc190byA9IGMoImNoYW1iZXJfaWQiLCAiLnZhbHVlIiksICMgU2VwYXJhdGUgY29sdW1uIG5hbWVzIGludG8gJ2lkJyBhbmQgb3RoZXIgdmFyaWFibGVzDQogICAgbmFtZXNfc2VwID0gIl8iDQogICkgJT4lIA0KICAgIGRwbHlyOjptdXRhdGUocmVzcGlyb21ldGVyX2dyb3VwID0gImQiKSAlPiUgDQogIGRwbHlyOjpyZW5hbWUoZGF0ZSA9IGlfZGF0ZSkNCg0Kc2xvcGVfbGlzdFtbZF9uYW1lXV0gPC0gZF9kZg0KfQ0KDQoNCnNsb3BlX2RmIDwtIGJpbmRfcm93cyhzbG9wZV9saXN0KSAlPiUgDQogIGRwbHlyOjptdXRhdGUocmVzcF9jYXRfZGF0ZSA9IHBhc3RlMChyZXNwaXJvbWV0ZXJfZ3JvdXAsICJfIiwgc3RhcnRfZGF0ZSksDQogICAgICAgICAgICAgICAgY2hhbWJlcl9uID0gc3RyX2V4dHJhY3QoY2hhbWJlcl9pZCwgIlxcZCsiKSwNCiAgICAgICAgICAgICAgICBpZF9wcm94ID0gcGFzdGUwKHJlc3BfY2F0X2RhdGUsICJfIiwgY2hhbWJlcl9uKSwNCiAgICAgICAgICAgICAgICB0aW1lX2htcyA9IGFzX2htcyh0aW1lKjM2MDApLA0KICAgICAgICAgICAgICAgIGRhdGVfY2hyID0gZm9ybWF0KGRhdGUsICIlZC8lbS8lWSIpDQogICAgICAgICAgICAgICAgKQ0KYGBgDQoNCiMjIEZpc2ggbWV0YWRhdGENCg0KKirwn5K/IG1ldGFkYXRhKio6IFRoaXMgaXMgdGhlIG1ldGEgZGF0YSBmb3IgZWFjaCBjaGFtYmVyDQoNCipOb3RlOiBXZSBhcmUgYWxzbyBhZGRpbmcgdm9sdW1lIGJhc2VkIG9uIGNoYW1iZXIgdHlwZS4qDQoNCmBgYHtyfQ0Kc2V0d2QoaW5wdXRfZGF0YV93ZCkNCg0KbWV0YWRhdGEgPC0gcmVhZF9leGNlbCgiZmlzaC1tZXRhLnhsc3giLCBuYSA9ICJOQSIpICU+JSANCiAgZHBseXI6Om11dGF0ZShpZF9zcGxpdCA9IGlkKSAlPiUgDQogIHRpZHlyOjpzZXBhcmF0ZShpZF9zcGxpdCwgaW50byA9IGMoInJlc3Bpcm9tZXRlcl9ncm91cCIsICJzYWxpbml0eV9ncm91cCIsICJzdGFydF9kYXRlIiwgImNoYW1iZXIiKSwgc2VwID0gIl8iKSAlPiUgDQogIGRwbHlyOjptdXRhdGUoDQogICAgICB2b2x1bWUgPSBkcGx5cjo6Y2FzZV93aGVuKA0KICAgICAgICBjaGFtYmVyX3R5cGUgPT0gIkwiIH4gMC4zMDAsDQogICAgICAgIGNoYW1iZXJfdHlwZSA9PSAiTV9NIiB+IDAuMTA1LA0KICAgICAgICBjaGFtYmVyX3R5cGUgPT0gIk1fTk0iIH4gMC4xMSwNCiAgICAgICAgY2hhbWJlcl90eXBlID09ICJTIiB+IDAuMDU4LA0KICAgICAgICBjaGFtYmVyX3R5cGUgPT0gIlNNIiB+IDAuMDc1LA0KICAgICAgICBjaGFtYmVyX3R5cGUgPT0gIkQzIiB+IDAuMDU1LA0KICAgICAgICBUUlVFIH4gTkENCiAgICAgICksDQogICAgICBpZF9wcm94ID0gcGFzdGUwKHJlc3Bpcm9tZXRlcl9ncm91cCwgIl8iLCBzdGFydF9kYXRlLCAiXyIsIGNoYW1iZXIpLA0KICAgICAgcmVsX3NpemUgPSBtYXNzL3ZvbHVtZSkNCmBgYA0KDQojIyBVcmJpbmEsIEdsb3ZlciwgYW5kIEZvcnN0ZXIgKDIwMTIpDQoNCioq8J+SvyB1cmJpbmFfZXRfYWxfMjAxMioqOiBUaGlzIGlzIHRoZSBtZWFuIGxldmVsIGRhdGEgZXh0cmFjdGVkIGZyb20gVXJiaW5hLCBHbG92ZXIsIGFuZCBGb3JzdGVyICgyMDEyKV5bMl1eIEZpZ3VyZSAxYS4gV2UgdXNlZCB0aGUgbWV0YURpZ2l0aXNlIHBhY2thZ2UgaW4gUiB0byBleHRyYWN0IHRoZSBkYXRhIF5bM11eLg0KDQpgYGB7cn0NCnNldHdkKGlucHV0X2RhdGFfd2QpDQoNCnVyYmluYV9ldF9hbF8yMDEyIDwtIHJlYWRfZXhjZWwoInVyYmluYS1ldC1hbC0yMDEyLWZpZzFhLnhsc3giKQ0KYGBgDQoNCiMjIE/igoJjcml0IHZpdXNhbCBpbnNwZWN0aW9uDQoNCioq8J+SvyBvMmNyaXRfY2hlY2sqKjogVGhpcyBkYXRhIGZyYW1lIGluY2x1ZGVzIHRoZSB2aXN1YWwgYmFzZWQgYXNzZXNzbWVudCBmb3IgT+KCgmNyaXQgZm9yIGFsbCBmaXNoIGluY2x1ZGVkIGluIHRoZSBhbmFseXNpcyAoKm4qID0gNTgpLiBUaGUgaW5zcGVjdGlvbnMgd2VyZSBtYWRlIHVzaW5nIGZpZ3VyZXMgZ2VuYnJhdGVkIGJ5IHRoZSBgcGxvdE8yY3JpdCgpYCBmdW5jdGlvbiwgYW5kIGNhbiBiZSB2aWV3ZWQgaW4gYGNvbWJpbmVkX2NoYWJvdF9wbG90cy5wZGZgLiBUaGUgdmlzdWFsIGFzc2Vzc21lbnQgd2FzIGRvbmUgaW5kZXBlbmRlbnRseSBieSBhbGwgYXV0aG9ycywgYW5kIHRoZSBwcmVzZW5jZSBvZiBhbiBP4oKCY3JpdHMgYWxsb2NhdGVkIHRvICd5ZXMnLCAnbm8nLCAnbWF5YmUnLiBJZiB5ZXMsIG9yIG1heWJlLCBhbiBlc3RpbWF0ZSBvZiB0aGUgZGlzc29sdmVkIG94eWdlbiBwZXJjZW50YWdlIHdhcyBnaXZlbi4gDQoNCkRpcmVjdG9yeSB0byB0aGUgZmlndXJlcyAgIA0KDQrwn5OBIGdtYWMtbW8yLTI0Lw0K4pSU4pSA4pSAIPCfk4Igb3V0cHV0LWZpZy8gIA0KICAgIOKUlOKUgOKUgCDwn5OCIG1vZGVsX2NoYWJvdC8gDQogICAgICAgICDilJTilIDilIAg8J+ThCBjb21iaW5lZF9jaGFib3RfcGxvdHMucGRmICAgDQoNCmBgYHtyfQ0Kc2V0d2QoaW5wdXRfZGF0YV93ZCkNCg0KbzJjcml0X2NoZWNrIDwtIHJlYWRfZXhjZWwoIm8yY3JpdC12aXN1YWwtYXNzZXNzbWVudC54bHN4IiwgbmEgPSAiTkEiKQ0KYGBgDQoNCiMjIyBDb21iaW5kaW5nIG1ldGFkYXRhDQoNCkFkZGluZyB0aGUgbWV0YSBkYXRhIHRvIHRoZSBzbG9wZXMgZGF0YSBmcmFtZQ0KDQpgYGB7cn0NCnNsb3BlX2RmXzIgPC0gc2xvcGVfZGYgJT4lIA0KICBkcGx5cjo6c2VsZWN0KC1zdGFydF9kYXRlLCAtcmVzcGlyb21ldGVyX2dyb3VwKSAlPiUgDQogIGxlZnRfam9pbihtZXRhZGF0YSwgYnkgPSAiaWRfcHJveCIpICU+JSANCiAgZHBseXI6Om11dGF0ZShsaWdodF9kYXJrID0gaWZfZWxzZSh0aW1lX2htcyA+PSBhcy5obXMoIjA3OjAwOjAwIikgJiB0aW1lX2htcyA8IGFzLmhtcygiMTk6MDA6MDAiKSwgImxpZ2h0IiwgImRhcmsiKSkgJT4lIA0KICBkcGx5cjo6YXJyYW5nZShpZCkNCmBgYA0KDQo8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+DQoNCiMg8J+nuSBEYXRhIHRpZHkNCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQojIyBOdW1iZXJzDQoNCldlIGhhdmUgKio2NCBmaXNoKiogd2l0aCBNT+KCgiBkYXRhDQoNCmBgYHtyfQ0KbiA8LSBzbG9wZV9kZl8yICU+JSANCiAgZHBseXI6OmZpbHRlcihjaGFtYmVyX2NvbmRpdGlvbiA9PSAiZmlzaCIpICU+JSANCiAgZHBseXI6OmRpc3RpbmN0KGlkKSAlPiUgDQogIG5yb3coLikNCg0KcGFzdGUwKCJuID0gIiwgbikNCmBgYA0KDQpXaXRoIDQ4IGZyb20gdGhlIDAgcHB0IGFuZCA0OCBmcm9tIDkgcHB0IGdyb3Vwcw0KDQpgYGB7cn0NCnNsb3BlX2RmXzIgJT4lIA0KICBkcGx5cjo6ZmlsdGVyKGNoYW1iZXJfY29uZGl0aW9uID09ICJmaXNoIikgJT4lDQogIGRwbHlyOjpncm91cF9ieShzYWxpbml0eV9ncm91cCkgJT4lIA0KICBkcGx5cjo6cmVmcmFtZSgnbiB0b3RhbCcgPSBsZW5ndGgodW5pcXVlKGlkKSkpICU+JSANCiAgZ3QoKSAlPiUgDQogIGNvbHNfbGFiZWwoDQogICAgc2FsaW5pdHlfZ3JvdXAgPSAiU2FsaW5pdHkgZ3JvdXAiDQogICkgJT4lIA0KICBjb2xzX2FsaWduKA0KICAgIGFsaWduID0gImNlbnRlciIsIA0KICAgIGNvbHVtbnMgPSBldmVyeXRoaW5nKCkNCiAgKQ0KYGBgDQoNCiMjIEZpc2ggc2l6ZQ0KDQpIZXJlIHdlIGNhbGN1bGF0ZSB0aGUgbWVhbiBsZW5ndGggYW5kIHNpemUgb2YgZmlzaCB1c2VkIGluIHRoZSBleHBlcmltZW50Lg0KDQpgYGB7cn0NCm1hc3NfbGVuZ3RoIDwtIHNsb3BlX2RmXzIgJT4lIA0KICBkcGx5cjo6ZmlsdGVyKGNoYW1iZXJfY29uZGl0aW9uID09ICJmaXNoIikgJT4lDQogIGRwbHlyOjpncm91cF9ieShpZCkgJT4lIA0KICBkcGx5cjo6c2FtcGxlX24oMSkgJT4lIA0KICBkcGx5cjo6dW5ncm91cCgpICU+JSANCiAgZHBseXI6OnJlZnJhbWUoeF9tYXNzID0gcm91bmQobWVhbihtYXNzLCBuYS5ybSA9IFRSVUUpLCAzKSwNCiAgICAgICAgICAgICAgICAgbWluX21hc3MgPSByb3VuZChtaW4obWFzcywgbmEucm0gPSBUUlVFKSwgMyksDQogICAgICAgICAgICAgICAgIG1heF9tYXNzID0gcm91bmQobWF4KG1hc3MsIG5hLnJtID0gVFJVRSksIDMpLA0KICAgICAgICAgICAgICAgICB4X2xlbmd0aCA9IHJvdW5kKG1lYW4obGVuZ3RoLCBuYS5ybSA9IFRSVUUpLCAyKSwNCiAgICAgICAgICAgICAgICAgbWluX2xlbmd0aCA9IHJvdW5kKG1pbihsZW5ndGgsIG5hLnJtID0gVFJVRSksIDIpLA0KICAgICAgICAgICAgICAgICBtYXhfbGVuZ3RoID0gcm91bmQobWF4KGxlbmd0aCwgbmEucm0gPSBUUlVFKSwgMikpDQoNCm1hc3NfbWVhbiA8LSBtYXNzX2xlbmd0aCAlPiUgDQogIHB1bGwoeF9tYXNzKQ0KDQptYXNzX21pbiA8LSBtYXNzX2xlbmd0aCAlPiUgDQogIHB1bGwobWluX21hc3MpDQoNCm1hc3NfbWF4IDwtIG1hc3NfbGVuZ3RoICU+JSANCiAgcHVsbChtYXhfbWFzcykNCg0KbGVuZ3RoX21lYW4gPC0gbWFzc19sZW5ndGggJT4lIA0KICBwdWxsKHhfbGVuZ3RoKQ0KDQpsZW5ndGhfbWluIDwtIG1hc3NfbGVuZ3RoICU+JSANCiAgcHVsbChtaW5fbGVuZ3RoKQ0KDQpsZW5ndGhfbWF4IDwtIG1hc3NfbGVuZ3RoICU+JSANCiAgcHVsbChtYXhfbGVuZ3RoKQ0KDQpwYXN0ZTAoIlRoZSBtZWFuIG1hc3Mgb2YgZmlzaCB3YXMgIiwgbWFzc19tZWFuLCAiIGcgKHJhbmdlOiAiLCBtYXNzX21pbiwgIi0iLCBtYXNzX21heCwgIikiLA0KICAgICAgICIsIGFuZCB0aGUgbWVhbiBsZW5ndGggd2FzICIsIGxlbmd0aF9tZWFuLCAiIG1tIChyYW5nZTogIiwgbGVuZ3RoX21pbiwgIi0iLCBsZW5ndGhfbWF4LCAiKSIpDQpgYGANCg0KIyMgRmlsdGVyaW5nIHRyaWFscw0KDQpXZSB3aWxsIHJlbW92ZSA2IHRyaWFscyB3aGljaCBoYWQgZXJyb3JzLiBUaGVzZSBhcmUgYXMgZm9sbG93czoNCg0KLSAgIGFfMF8yNW5vdl8zIGZpc2ggZGllZCBkdXJpbmcgdHJpYWwNCi0gICBiXzBfMjZub3ZfNCBmbGF0IGxpbmVkIGVhcmx5DQotICAgY18wXzIybm92XzIgY2hhbWJlciB3YXMgb3BlbmVkIGVhcmx5DQotICAgY185XzI2bm92XzIgY2hhbWJlciB3YXMgb3BlbmVkIGVhcmx5DQotICAgY185XzI2bm92XzQgY2hhbWJlciB3YXMgb3BlbmVkIGVhcmx5DQotICAgZF85XzI3bm92XzMgc2Vuc29yIHdhcyBqdW1weSBhbmQgZW5kIHBvaW50cyB3ZXJlIGhhcmQgdG8gY29uZmlkZW50bHkgSUQgdmlzdWFsbHkNCg0KYGBge3J9DQpyZW1vdmVfdHJpYWxfZXJyb3IgPC0gYygiYV8wXzI1bm92XzMiLCAiYl8wXzI2bm92XzQiLCAiY18wXzIybm92XzIiLCAiY185XzI2bm92XzIiLCAiY185XzI2bm92XzQiLCAiZF85XzI3bm92XzMiKQ0KDQpzbG9wZV9kZl9maWx0ZXIgPC0gc2xvcGVfZGZfMiAlPiUgDQogIGRwbHlyOjpmaWx0ZXIoIShpZCAlaW4lIHJlbW92ZV90cmlhbF9lcnJvcikpDQpgYGANCg0KV2Ugbm93IGhhdmUgKio1OCBmaXNoKiogd2l0aCBNTzIgZGF0YQ0KDQpgYGB7cn0NCm4gPC0gc2xvcGVfZGZfZmlsdGVyICU+JSANCiAgZHBseXI6OmZpbHRlcihjaGFtYmVyX2NvbmRpdGlvbiA9PSAiZmlzaCIpICU+JSANCiAgZHBseXI6OmRpc3RpbmN0KGlkKSAlPiUgDQogIG5yb3coLikNCg0KcGFzdGUwKCJuID0gIiwgbikNCmBgYA0KDQpXaXRoIDMwIGluIHRoZSAwIHBwdCBncm91cCBhbmQgMjggaW4gdGhlIDkgcHB0IGdyb3VwDQoNCmBgYHtyfQ0Kc2xvcGVfZGZfZmlsdGVyICU+JSANCiAgZHBseXI6OmZpbHRlcihjaGFtYmVyX2NvbmRpdGlvbiA9PSAiZmlzaCIpICU+JQ0KICBkcGx5cjo6Z3JvdXBfYnkoc2FsaW5pdHlfZ3JvdXApICU+JSANCiAgZHBseXI6OnJlZnJhbWUoJ24gdG90YWwnID0gbGVuZ3RoKHVuaXF1ZShpZCkpKSAlPiUgDQogIGd0KCkgJT4lIA0KICBjb2xzX2xhYmVsKA0KICAgIHNhbGluaXR5X2dyb3VwID0gIlNhbGluaXR5IGdyb3VwIg0KICApICU+JSANCiAgY29sc19hbGlnbigNCiAgICBhbGlnbiA9ICJjZW50ZXIiLCANCiAgICBjb2x1bW5zID0gZXZlcnl0aGluZygpDQogICkNCmBgYA0KDQpNYXNzIGFuZCBzaXplIG9mIGZpc2ggYWZ0ZXIgcmVtb3ZpbmcgNiB0cmlhbHMgd2hpY2ggaGFkIGVycm9ycw0KDQpgYGB7cn0NCm1hc3NfbGVuZ3RoIDwtIHNsb3BlX2RmX2ZpbHRlciAlPiUgDQogIGRwbHlyOjpmaWx0ZXIoY2hhbWJlcl9jb25kaXRpb24gPT0gImZpc2giKSAlPiUNCiAgZHBseXI6Omdyb3VwX2J5KGlkKSAlPiUgDQogIGRwbHlyOjpzYW1wbGVfbigxKSAlPiUgDQogIGRwbHlyOjp1bmdyb3VwKCkgJT4lIA0KICBkcGx5cjo6cmVmcmFtZSh4X21hc3MgPSByb3VuZChtZWFuKG1hc3MsIG5hLnJtID0gVFJVRSksIDMpLA0KICAgICAgICAgICAgICAgICBtaW5fbWFzcyA9IHJvdW5kKG1pbihtYXNzLCBuYS5ybSA9IFRSVUUpLCAzKSwNCiAgICAgICAgICAgICAgICAgbWF4X21hc3MgPSByb3VuZChtYXgobWFzcywgbmEucm0gPSBUUlVFKSwgMyksDQogICAgICAgICAgICAgICAgIHhfbGVuZ3RoID0gcm91bmQobWVhbihsZW5ndGgsIG5hLnJtID0gVFJVRSksIDIpLA0KICAgICAgICAgICAgICAgICBtaW5fbGVuZ3RoID0gcm91bmQobWluKGxlbmd0aCwgbmEucm0gPSBUUlVFKSwgMiksDQogICAgICAgICAgICAgICAgIG1heF9sZW5ndGggPSByb3VuZChtYXgobGVuZ3RoLCBuYS5ybSA9IFRSVUUpLCAyKSkNCg0KbWFzc19tZWFuIDwtIG1hc3NfbGVuZ3RoICU+JSANCiAgcHVsbCh4X21hc3MpDQoNCm1hc3NfbWluIDwtIG1hc3NfbGVuZ3RoICU+JSANCiAgcHVsbChtaW5fbWFzcykNCg0KbWFzc19tYXggPC0gbWFzc19sZW5ndGggJT4lIA0KICBwdWxsKG1heF9tYXNzKQ0KDQpsZW5ndGhfbWVhbiA8LSBtYXNzX2xlbmd0aCAlPiUgDQogIHB1bGwoeF9sZW5ndGgpDQoNCmxlbmd0aF9taW4gPC0gbWFzc19sZW5ndGggJT4lIA0KICBwdWxsKG1pbl9sZW5ndGgpDQoNCmxlbmd0aF9tYXggPC0gbWFzc19sZW5ndGggJT4lIA0KICBwdWxsKG1heF9sZW5ndGgpDQoNCnBhc3RlMCgiVGhlIG1lYW4gbWFzcyBvZiBmaXNoIHdhcyAiLCBtYXNzX21lYW4sICIgZyAocmFuZ2U6ICIsIG1hc3NfbWluLCAiLSIsIG1hc3NfbWF4LCAiKSIsDQogICAgICAgIiwgYW5kIHRoZSBtZWFuIGxlbmd0aCB3YXMgIiwgbGVuZ3RoX21lYW4sICIgbW0gKHJhbmdlOiAiLCBsZW5ndGhfbWluLCAiLSIsIGxlbmd0aF9tYXgsICIpIikNCmBgYA0KDQpDaGFtYmVyIHNpemUgYnJlYWtkb3duDQoNCmBgYHtyfQ0Kc2xvcGVfZGZfZmlsdGVyICU+JSANCiAgZHBseXI6OmZpbHRlcihjaGFtYmVyX2NvbmRpdGlvbiA9PSAiZmlzaCIpICU+JQ0KICBkcGx5cjo6bXV0YXRlKHZvbHVtZSA9IGlmX2Vsc2Uodm9sdW1lID09IDAuMDU1LCAwLjA1OCwgdm9sdW1lKSkgJT4lIA0KICBkcGx5cjo6Z3JvdXBfYnkodm9sdW1lKSAlPiUgDQogIGRwbHlyOjpyZWZyYW1lKCduIHRvdGFsJyA9IGxlbmd0aCh1bmlxdWUoaWQpKSwNCiAgICAgICAgICAgICAgICAgbWVkaWFuX21hc3MgPSBtZWRpYW4obWFzcywgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAgICAgICAgc2RfbWFzcyA9IHNkKG1hc3MsIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZ3QoKSAlPiUgDQogIGNvbHNfbGFiZWwoDQogICAgdm9sdW1lID0gIkNoYW1iZXIgdHlwZSIsDQogICAgbWVkaWFuX21hc3MgPSAiTWVkaWFuIG1hc3MiLA0KICAgIHNkX21hc3MgPSAiU3RhbmRhcmQgZGV2aWF0aW9uIG1hc3MiDQogICkgJT4lIA0KICBjb2xzX2FsaWduKA0KICAgIGFsaWduID0gImNlbnRlciIsIA0KICAgIGNvbHVtbnMgPSBldmVyeXRoaW5nKCkNCiAgKQ0KYGBgDQoNCk51bWJlcnMgcGVyIHRyaWFsIGFwcHJvYWNoDQoNCmBgYHtyfQ0KcGhhc2VzIDwtIGMoIjUwYyIsICIxMDBjIikNCg0Kc2xvcGVfZGZfZmlsdGVyICU+JSANCiAgZHBseXI6OmZpbHRlcihjaGFtYmVyX2NvbmRpdGlvbiA9PSAiZmlzaCIgJiBwaGFzZSAlaW4lIHBoYXNlcykgJT4lDQogIGRwbHlyOjpncm91cF9ieShwaGFzZSkgJT4lIA0KICBkcGx5cjo6cmVmcmFtZSgnbiB0b3RhbCcgPSBsZW5ndGgodW5pcXVlKGlkKSkpICU+JSANCiAgZ3QoKSAlPiUgDQogIGNvbHNfbGFiZWwoDQogICAgcGhhc2UgPSAiVHlwZSBvZiB0cmlhbCIsDQogICkgJT4lIA0KICBjb2xzX2FsaWduKA0KICAgIGFsaWduID0gImNlbnRlciIsIA0KICAgIGNvbHVtbnMgPSBldmVyeXRoaW5nKCkNCiAgKQ0KYGBgDQoNCiMjIEZpbHRlcmluZyBNT+KCgiBlc3RpbWF0ZXMNCg0KSGVyZSB3ZSBhcHBseSB0aGUgZm9sbG93aW5nIGZpbHRlcnMgdG8gdGhlIE1P4oKCIGRhdGE6DQoNCi0gICBSZW1vdmUgdGhlIGZpcnN0IDUgU01SIGN5Y2xlcyAoYnVybiBpbikNCi0gICBSZW1vdmUgYWxsIHBvc2l0aXZlIHJhdyBzbG9wZXMNCi0gICBSZW1vdmUgYWxsIE1P4oKCIGNhbGN1bGF0ZWQgdXNpbmcgbGVzcyB0aGVuIDYwIGRhdGEgcG9pbnRzICg1IG1pbiBhdCAwLjIgSHopDQotICAgUmVtb3ZlIGFsbCBNT+KCgiBjYWxjdWxhdGVkIGlmIE/igoIgaW5jcmVhc2VzIGluIGEgY2xvc2VkIHBoYXNlIChpLmUuIHRyaWFsIGhhcyBlbmRlZCkNCg0KQ2hlY2sgcG9zaXRpdmUgdmFsdWVzIGZvciBNT+KCgiBiZWZvcmUgcmVtb3ZpbmcuDQoNCmBgYHtyfQ0Kc2xvcGVfdGlkeV9yZW1vdmVfZmx1c2ggPC0gc2xvcGVfZGZfZmlsdGVyICU+JQ0KICBkcGx5cjo6ZmlsdGVyKHBoYXNlICE9ICJzbXIiLCBjaGFtYmVyX2NvbmRpdGlvbiA9PSAiZmlzaCIpICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KGlkKSAlPiUNCiAgZHBseXI6OmFycmFuZ2UoaWQsIG9yZGVyKSAlPiUgICMgRW5zdXJlIHRoZSBkYXRhIGlzIHNvcnRlZCB3aXRoaW4gZWFjaCBncm91cA0KICBkcGx5cjo6bXV0YXRlKG8yX2RpZmYgPSBpZl9lbHNlKHJvd19udW1iZXIoKSA9PSAxLCAwLCBvMiAtIGxhZyhvMikpLCAjIENhbGN1bGF0ZSB0aGUgZGlmZmVyZW5jZSBpbiAnbzInDQogICAgICAgICAgICAgICAgbzJfZGlmZl9jdW1zdW0gPSBjdW1zdW0obzJfZGlmZiA+IDEpKSAlPiUgICMgQ2hlY2tzIGZpcnN0IG9jY3VycmVuY2UgYW5kIHN1bXMgDQogIGRwbHlyOjpmaWx0ZXIobzJfZGlmZl9jdW1zdW0gPT0gMCkgJT4lICAjIEtlZXAgcm93cyB1bnRpbCB0aGUgZmlyc3QganVtcCA+IDENCiAgZHBseXI6OnVuZ3JvdXAoKSAlPiUNCiAgZHBseXI6OnNlbGVjdCgtbzJfZGlmZiwgLW8yX2RpZmZfY3Vtc3VtKQ0KDQpwb3N0aXZlX3Nsb3BlcyA8LSBzbG9wZV90aWR5X3JlbW92ZV9mbHVzaCAlPiUNCiAgZHBseXI6OmZpbHRlcihjaGFtYmVyX2NvbmRpdGlvbiA9PSAiZmlzaCIgJiBtbzJjb3JyID4gMCkNCg0Kbl9wb3N0aXZlX3Nsb3BlcyA8LSBucm93KHBvc3RpdmVfc2xvcGVzKQ0KDQpuX3Nsb3BlcyA8LSAgbnJvdyhzbG9wZV90aWR5X3JlbW92ZV9mbHVzaCkNCg0KbGlzdF9wb3N0aXZlX2FsbCA8LSBwb3N0aXZlX3Nsb3BlcyAlPiUgDQogIGRwbHlyOjpkaXN0aW5jdChpZCkgJT4lIA0KICBkcGx5cjo6cHVsbChpZCkNCg0KcHJpbnQocGFzdGUwKCJUaGVyZSBhcmUgIiwgbGVuZ3RoKGxpc3RfcG9zdGl2ZV9hbGwpLCAiIGZpc2ggd2l0aCBwb3N0aXZlIHNsb3Blcy4gVGhlc2UgZmlzaCBhcmU6ICIsIHBhc3RlKGxpc3RfcG9zdGl2ZV9hbGwsIGNvbGxhcHNlID0gIiwgIiksICIuIEZvciBhbGwgZXN0aW1hdGVkIHNsb3BlcyAobiA9ICIsIG5fc2xvcGVzLCAiKSAiLCByb3VuZCgobl9wb3N0aXZlX3Nsb3Blcy9uX3Nsb3BlcykqMTAwLDIpICwgIiUgd2VyZSBwb3N0aXZlIChuID0gIiwgbl9wb3N0aXZlX3Nsb3BlcywgIikiKSkNCmBgYA0KDQpGaWx0ZXJpbmcgdGhlIE1P4oKCIGRhdGENCg0KYGBge3J9DQpjeWNsZV9idXJuIDwtIDA6NA0KDQpzbG9wZV9kZl9maWx0ZXJfMSA8LSBzbG9wZV9kZl9maWx0ZXIgJT4lDQogIGRwbHlyOjpmaWx0ZXIoIShjeWNsZSAlaW4lIGN5Y2xlX2J1cm4pICYgDQogICAgICAgICAgICAgICAgICBtbzJjb3JyIDwgMCAmIA0KICAgICAgICAgICAgICAgICAgbiA+IDYwICYNCiAgICAgICAgICAgICAgICAgIGNoYW1iZXJfY29uZGl0aW9uID09ICJmaXNoIg0KICAgICAgICAgICAgICAgICkNCiAgDQojIEZpbHRlciBvdXQgdGhlIGVuZCBmbHVzaA0Kc2xvcGVfdGlkeV9jbG9zZWQgPC0gc2xvcGVfZGZfZmlsdGVyXzEgJT4lDQogIGRwbHlyOjpmaWx0ZXIocGhhc2UgIT0gInNtciIpICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KGlkKSAlPiUNCiAgZHBseXI6OmFycmFuZ2UoaWQsIG9yZGVyKSAlPiUgICMgRW5zdXJlIHRoZSBkYXRhIGlzIHNvcnRlZCB3aXRoaW4gZWFjaCBncm91cA0KICBkcGx5cjo6bXV0YXRlKG8yX2RpZmYgPSBpZl9lbHNlKHJvd19udW1iZXIoKSA9PSAxLCAwLCBvMiAtIGxhZyhvMikpLCAjIENhbGN1bGF0ZSB0aGUgZGlmZmVyZW5jZSBpbiAnbzInDQogICAgICAgICAgICAgICAgbzJfZGlmZl9jdW1zdW0gPSBjdW1zdW0obzJfZGlmZiA+IDEpKSAlPiUgICMgQ2hlY2tzIGZpcnN0IG9jY3VycmVuY2UgYW5kIHN1bXMgDQogIGRwbHlyOjpmaWx0ZXIobzJfZGlmZl9jdW1zdW0gPT0gMCkgJT4lICAjIEtlZXAgcm93cyB1bnRpbCB0aGUgZmlyc3QganVtcCA+IDENCiAgZHBseXI6OnVuZ3JvdXAoKSAlPiUNCiAgZHBseXI6OnNlbGVjdCgtbzJfZGlmZiwgLW8yX2RpZmZfY3Vtc3VtKQ0KDQpzbG9wZV90aWR5X3NtciA8LSBzbG9wZV9kZl9maWx0ZXJfMSAlPiUgDQogIGRwbHlyOjpmaWx0ZXIocGhhc2UgPT0gInNtciIpDQoNCnNsb3BlX2RmX2ZpbHRlcl8yIDwtIHJiaW5kKHNsb3BlX3RpZHlfc21yLCBzbG9wZV90aWR5X2Nsb3NlZCkgJT4lIA0KICBkcGx5cjo6YXJyYW5nZShpZCwgb3JkZXIpDQpgYGANCg0KIyMgQ2FsY3VsYXRpbmcgU01SDQoNCldlIHdpbGwgY2FsY3VsYXRlIFNNUiB1c2luZyBgY2FsY1NNUmAgZnVuY3Rpb24gYnkgQ2hhYm90LCBTdGVmZmVuc2VuIGFuZCBGYXJyZWxsICgyMDE2KV5bMV1eLiBTcGVjaWZpY2FsbHksIHdlIHVzZSBtZWFuIG9mIHRoZSBsb3dlc3Qgbm9ybWFsIGRpc3RyaWJ1dGlvbiAoTUxORCkgd2hlcmUgQ1ZtbG5kIFw8IDUuNCBhbmQgdGhlIG1lYW4gb2YgdGhlIGxvd2VyIDIwJSBxdWFudGlsZSAocTAuMikgd2VyZSBDVm1sbmQgXD4gNS40LiBJZiBDVm1sbmQgaXMgbm90IGNhbGN1bGF0ZWQgd2UgaGF2ZSB1c2VkIHEwLjIuDQoNCmBgYHtyfQ0KbGFiY2hhcnRfY2hhYm90X3NtciA8LSBzbG9wZV9kZl9maWx0ZXJfMiAlPiUNCiAgZHBseXI6OmZpbHRlcihwaGFzZSA9PSAic21yIikNCg0KIyBFeHRyYWN0IGRpc3RpbmN0IElEcw0KaWRzIDwtIGxhYmNoYXJ0X2NoYWJvdF9zbXIgJT4lIA0KICBkcGx5cjo6ZGlzdGluY3QoaWQpICU+JSANCiAgZHBseXI6OnB1bGwoKQ0KDQojIEluaXRpYWxpc2UgYW4gZW1wdHkgbGlzdCB0byBzdG9yZSBTTVIgZGF0YQ0Kc21yX2xpc3QgPC0gbGlzdCgpDQoNCiMgUHJvY2VzcyBlYWNoIElEDQpmb3IgKGlkX2kgaW4gaWRzKSB7DQogIHRyeUNhdGNoKHsNCiAgICAjIEZpbHRlciB0aGUgZGF0YSBmb3IgdGhlIGN1cnJlbnQgSUQNCiAgICBkZl9pIDwtIGxhYmNoYXJ0X2NoYWJvdF9zbXIgJT4lIA0KICAgICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUgDQogICAgICBkcGx5cjo6bXV0YXRlKGFic19tbzJjb3JyID0gYWJzKG1vMmNvcnIpKQ0KICAgIA0KICAgICMgQ2FsY3VsYXRlIFNNUiByZXN1bHRzDQogICAgY2FsY1NNUl9yZXN1bHRzIDwtIGNhbGNTTVIoZGZfaSRhYnNfbW8yY29ycikNCiAgICBDVm1sbmRfaSA8LSBjYWxjU01SX3Jlc3VsdHMkQ1ZtbG5kDQogICAgcXVhbnRfaSA8LSBjYWxjU01SX3Jlc3VsdHMkcXVhbnQgJT4lIGFzX3RpYmJsZSgpDQogICAgcXVhbnRfMjBwZXJfaSA8LSBxdWFudF9pJHZhbHVlWzNdDQogICAgbWxuZF9pIDwtIGNhbGNTTVJfcmVzdWx0cyRtbG5kDQogICAgc21yX3ZhbHVlIDwtIGlmX2Vsc2UoQ1ZtbG5kX2kgPCA1LjQsIG1sbmRfaSwgcXVhbnRfMjBwZXJfaSkNCiAgICBzbXJfdHlwZSA8LSBpZl9lbHNlKENWbWxuZF9pIDwgNS40LCAibWxuZCIsICJxdWFudF8yMHBlciIpDQogICAgc21yX3ZhbHVlIDwtIGlmX2Vsc2UoaXMubmEoc21yX3ZhbHVlKSwgcXVhbnRfMjBwZXJfaSwgc21yX3ZhbHVlKQ0KICAgIHNtcl90eXBlIDwtIGlmX2Vsc2UoaXMubmEoc21yX3R5cGUpLCAicXVhbnRfMjBwZXIiLCBzbXJfdHlwZSkNCiAgICANCiAgICAjIENyZWF0ZSBhIGRhdGEgZnJhbWUgZm9yIHRoZSBjdXJyZW50IElEDQogICAgc21yX2RmX2kgPC0gdGliYmxlOjp0aWJibGUoDQogICAgICBpZCA9IGlkX2ksDQogICAgICBzbXIgPSBzbXJfdmFsdWUsDQogICAgICBzbXJfZXN0ID0gc21yX3R5cGUNCiAgICApDQogICAgDQogIH0sIGVycm9yID0gZnVuY3Rpb24oZSkgew0KICAgICMgSGFuZGxlIGVycm9ycyBieSBhc3NpZ25pbmcgTkEgdmFsdWVzDQogICAgc21yX2RmX2kgPC0gdGliYmxlOjp0aWJibGUoDQogICAgICBpZCA9IGlkX2ksDQogICAgICBzbXIgPSBOQSwNCiAgICAgIHNtcl9lc3QgPSBOQQ0KICAgICkNCiAgfSkNCiAgDQogICMgQXBwZW5kIHRvIHRoZSBsaXN0DQogIHNtcl9saXN0W1tpZF9pXV0gPC0gc21yX2RmX2kNCn0NCg0KIyBDb21iaW5lIGFsbCBpbmRpdmlkdWFsIFNNUiBkYXRhIGZyYW1lcyBpbnRvIG9uZQ0Kc21yX2RmIDwtIGJpbmRfcm93cyhzbXJfbGlzdCkgJT4lIA0KICBkcGx5cjo6cmVuYW1lKHNtcl9jaGFib3QgPSBzbXIsDQogICAgICAgICAgICAgICAgc21yX2NoYWJvdF9tZXRob2QgPSBzbXJfZXN0KQ0KDQpzbG9wZV9kZl9maWx0ZXJfMyA8LSBzbG9wZV9kZl9maWx0ZXJfMiAlPiUNCiAgZHBseXI6OmxlZnRfam9pbiguLCBzbXJfZGYsIGJ5ID0gImlkIikNCmBgYA0KDQojIyBUcmFuc2Zvcm1pbmcgTU/igoINCg0KSGVyZSB3ZSBhcmUgdHJhbnNmb3JtaW5nIHRoZSBNT+KCgiB1bml0cy4gVGhlIHJlc3VsdGluZyB2YWx1ZXMgYXJlIGFzIGZvbGxvd3M6DQoNCi0gICAqKk1PMioqIGlzIGFic29sdXRlIHZhbHVlIG9mIHRoZSBiYWNrZ3JvdW5kIGFuZCBsZWFrIGNvcnJlY3RlZCBNT+KCgiBzbG9wZSBmcm9tIExhYmNoYXJ0IChtbzJjb3JyKSB0aW1lcyB0aGUgbmV0IHZvbHVtZSBvZiB0aGUgY2hhbWJlciAodm9sdW1lIC0gZmlzaCBtYXNzKSwgw5cgNjAsIMOXIDYwLCB0byBhY2hpZXZlIE1P4oKCIGFzIG1nXi0xXiBP4oKCIGheLTFeDQoNCi0gICAqKk1PMl9nKiogaXMgTU8yIGRpdmlkZWQgYnkgZmlzaCBtYXNzIHRvIGFjaGlldmUgTU/igoIgYXMgbWdeLTFeIE/igoIgZ14tMV4gaF4tMV4gKGkuZS4gbWFzcyBzdGFuZGFyZGlzZWQpDQoNCi0gICAqKlNNUioqIGFic29sdXRlIHZhbHVlIG9mIHRoZSBTTVIgZXN0aW1hdGVzIHVzaW5nIG1ldGhvZHMgZGVzY3JpYmVkIGJ5IENoYWJvdCwgU3RlZmZlbnNlbiBhbmQgRmFycmVsbCAoMjAxNileWzFdXiB0aW1lcyB0aGUgbmV0IHZvbHVtZSBvZiB0aGUgY2hhbWJlciAodm9sdW1lIC0gZmlzaCBtYXNzKSwgw5cgNjAsIMOXIDYwLCB0byBhY2hpZXZlIFNNUiBhcyBtZ14tMV4gT+KCgiBoXi0xXikNCg0KLSAgICoqU01SX2cqKiBpcyBTTVIgZGl2aWRlZCBieSBmaXNoIG1hc3MgdG8gYWNoaWV2ZSBTTVIgYXMgbWdeLTFeIE/igoIgZ14tMV4gaF4tMV4gKGkuZS4gbWFzcyBzdGFuZGFyZGlzZWQpDQoNCi0gICAqKkRPKiogaXMgZGlzc29sdmVkIG94eWdlbiBwZXJjZW50YWdlIGNhbGN1bGF0ZWQgZnJvbSBP4oKCIHZhbHVlcyAobWdeLTFeIExeLTFeKSB1c2luZyB0aGUgcmVjb3JkZWQgdGVtcGVyYXR1cmUsIHNhbGluaXR5LCBhbmQgYSBjb25zdGFudCBhdG1vc3BoZXJpYyBwcmVzc3VyZSAoUGE7IDEwMTMuMjUpDQoNCi0gICAqKm8yX2twYSoqIGlzIHRoZSBP4oKCIGNvbmNlbnRyYXRpb24gaW4ga2lsb3Bhc2NhbCAoa3BhKS4gVGhpcyBpcyB1c2VkIHRvIG1ha2UgYSBjb21wYXJhdGl2ZSBmaWd1cmUgb25seS4NCg0KYGBge3J9DQojIENvbWJpbmUgYmFjayBpbnRvIG9uZSBkYXRhIGZyYW1lDQpzbG9wZV90aWR5IDwtIHNsb3BlX2RmX2ZpbHRlcl8zICU+JSANCiAgICBkcGx5cjo6bXV0YXRlKERPID0gY29udl9vMigNCiAgICAgICAgICAgICAgICAgICBvMiA9IG8yLA0KICAgICAgICAgICAgICAgICAgIGZyb20gPSAibWdfcGVyX2wiLA0KICAgICAgICAgICAgICAgICAgIHRvID0gInBlcmNlbnRfYS5zLiIsDQogICAgICAgICAgICAgICAgICAgdGVtcCA9IHRlbXAsICNDDQogICAgICAgICAgICAgICAgICAgc2FsID0gbWVhc3VyZWRfc2FsaW5pdHksDQogICAgICAgICAgICAgICAgICAgYXRtX3ByZXMgPSAxMDEzLjI1KSwNCiAgICAgICAgICAgICAgICAgIG8yX2twYSA9IGNvbnZfbzIoDQogICAgICAgICAgICAgICAgICAgbzIgPSBvMiwNCiAgICAgICAgICAgICAgICAgICBmcm9tID0gIm1nX3Blcl9sIiwNCiAgICAgICAgICAgICAgICAgICB0byA9ICJrUGEiLA0KICAgICAgICAgICAgICAgICAgIHRlbXAgPSB0ZW1wLCAjQw0KICAgICAgICAgICAgICAgICAgIHNhbCA9IG1lYXN1cmVkX3NhbGluaXR5LA0KICAgICAgICAgICAgICAgICAgIGF0bV9wcmVzID0gMTAxMy4yNSksDQogICAgICAgICAgICAgICAgICBuZXRfdm9sdW1lID0gdm9sdW1lIC0gbWFzcy8xMDAwLA0KICAgICAgICAgICAgICAgICAgTU8yID0gYWJzKG1vMmNvcnIpKm5ldF92b2x1bWUqNjAqNjAsDQogICAgICAgICAgICAgICAgICBNTzJfZyA9IE1PMi9tYXNzLA0KICAgICAgICAgICAgICAgICAgU01SID0gYWJzKHNtcl9jaGFib3QpKm5ldF92b2x1bWUqNjAqNjAsDQogICAgICAgICAgICAgICAgICBTTVJfZyA9IFNNUi9tYXNzDQogICAgICAgICAgICAgICAgICApDQpgYGANCg0KVHJpYWwgbGVuZ3Rocw0KDQpgYGB7cn0NCnNsb3BlX3RpZHkgJT4lIA0KICBkcGx5cjo6ZmlsdGVyKHBoYXNlICE9ICJzbXIiKSAlPiUgDQogIGRwbHlyOjogbXV0YXRlKGRhdGV0aW1lID0gYXMuUE9TSVhjdChwYXN0ZShkYXRlLCB0aW1lX2htcyksIGZvcm1hdCA9ICIlWS0lbS0lZCAlSDolTTolUyIpKSAlPiUNCiAgZHBseXI6Omdyb3VwX2J5KGlkKSAlPiUgDQogIGRwbHlyOjpyZWZyYW1lKA0KICAgIHBoYXNlID0gcGhhc2VbMV0sDQogICAgc3RhcnRfdGltZSA9IG1pbihkYXRldGltZSwgbmEucm0gPSBUUlVFKSwNCiAgICBlbmRfdGltZSA9IG1heChkYXRldGltZSwgbmEucm0gPSBUUlVFKSwNCiAgICB0aW1lX2RpZmYgPSBkaWZmdGltZShlbmRfdGltZSwgc3RhcnRfdGltZSwgdW5pdHMgPSAiaG91cnMiKSAgIyBDaGFuZ2UgdW5pdHMgYXMgbmVlZGVkDQogICkgJT4lIA0KICBkcGx5cjo6Z3JvdXBfYnkocGhhc2UpICU+JSANCiAgZHBseXI6OnJlZnJhbWUoJ01pbmltdW0gZHVyYXRpb24nID0gcm91bmQobWluKHRpbWVfZGlmZiksMiksDQogICAgICAgICAgICAgICAgICdNYXhpbXVtIGR1cmF0aW9uJyA9IHJvdW5kKG1heCh0aW1lX2RpZmYpLDIpLA0KICAgICAgICAgICAgICAgICAnTWVkaWFuIGR1cmF0aW9uJyA9IHJvdW5kKG1lZGlhbih0aW1lX2RpZmYpLDIpKSAlPiUgDQogIGRwbHlyOjptdXRhdGUocGhhc2UgPSBpZl9lbHNlKHBoYXNlID09ICIxMDBjIiwgIkNsb3NlZCBhdCAxMDAlIGFpciBzYXR1cmF0aW9uIiwgIkNsb3NlZCBhdCA3NSUgYW5kIDUwJSBhaXIgc2F0dXJhdGlvbiIpKSAlPiUgDQogIGRwbHlyOjpyZW5hbWUoQXBwcm9hY2ggPSBwaGFzZSkgJT4lIA0KICBndCgpDQogIA0KYGBgDQoNCiMjIFZpc3VhbGlzaW5nIE1PMiBjb3JyZWN0aW9ucyAgDQoNCkxldCdzIGNoZWNrIGhvdyBkYXRhIGNvcnJlY3Rpb25zIGNoYW5nZSB0aGUgYXBwZWFyYW5jZSBvZiBvdXQgZGF0YSANCk1PMg0KDQpMZXQncyBjb21wYXJlIHJhdyBNTzIgY2FsY3VsYXRpb25zIChtbzIpLCBNTzIgY2FsY3VsYXRpb25zIGFmdGVyIGNvcnJlY3RpbmcgYmFja2dyb3VuZCByZXNwaXJhdGlvbiAobW8yX2Jncm91bmQpLCBhbmQgTU8yIGNhbGN1bGF0aW9ucyBhZnRlciBjb3JyZWN0aW5nIGZvciBiYWNrZ3JvdW5kIHJlc3BpcmF0aW9uIGFuZCBveHlnZW4gZGlmZnVzaW9uIGR5bmFtaWNzIChtbzJjb3JyKS4gRmlyc3Qgd2Ugd2lsbCBuZWVkIHRvIG1ha2UgdGhlIG1vMl9iZ3JvdW5kIHZhdWxlIGFzIGl0J3Mgbm90IHByZXNlbnQgaW4gdGhlIGRhdGFmaWxlLCBhbmQgdHJhbnNmb3JtIHRoZSBkYXRhIHRvIGxvbmcgZm9ybWF0ZSwgc28gd2UgY2FuIHBsb3QgaXQgbW9yZSBlYXNseS4NCg0KDQpgYGB7cn0NCnNsb3BlX2NvcnJfY29tcCA8LSBzbG9wZV90aWR5ICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KGlkKSAlPiUgDQogIGRwbHlyOjptdXRhdGUoDQogICAgTU8yX3JhdyA9IGFicyhtbzIpICogbmV0X3ZvbHVtZSAqIDYwICogNjAsDQogICAgTU8yX2Jncm91bmRfY29yciA9IGFicyhtbzIgLSBiZ3JvdW5kKSAqIG5ldF92b2x1bWUgKiA2MCAqIDYwLA0KICAgIE1PMl9jb3JyID0gYWJzKG1vMmNvcnIpICogbmV0X3ZvbHVtZSAqIDYwICogNjANCiAgKSAlPiUgDQogIGRwbHlyOjpzZWxlY3QoaWQsIG9yZGVyLCBETywgTU8yX3JhdywgTU8yX2Jncm91bmRfY29yciwgTU8yX2NvcnIpICU+JSANCiAgdGlkeXI6OnBpdm90X2xvbmdlcigNCiAgICBjb2xzID0gYyhNTzJfcmF3LCBNTzJfYmdyb3VuZF9jb3JyLCBNTzJfY29yciksIA0KICAgIG5hbWVzX3RvID0gIk1PMl90eXBlIg0KICApICU+JQ0KICBkcGx5cjo6bXV0YXRlKA0KICAgIE1PMl90eXBlID0gZm9yY2F0czo6ZmN0X3JlbGV2ZWwoTU8yX3R5cGUsICJNTzJfcmF3IiwgIk1PMl9iZ3JvdW5kX2NvcnIiLCAiTU8yX2NvcnIiKQ0KICApICU+JQ0KICBkcGx5cjo6dW5ncm91cCgpDQpgYGANCg0KIyMjIEZpZ3VyZSBTMQ0KDQpOb3cgbGV0J3MgcGxvdCB0aGVtIGluIHRoZSBzYW1lIGdyYXBoIGZvciBlYWNoIGZpc2g6IA0KPHNwYW4gc3R5bGU9ImNvbG9yOiNmNjkyQjQiPnJhdyBNT+KCgiBjYWxjdWxhdGlvbnM8L3NwYW4+IGFyZSBzaG93biBpbiBwaW5rLCANCjxzcGFuIHN0eWxlPSJjb2xvcjojNkU3ODg5Ij5NT+KCgiBjYWxjdWxhdGlvbnMgYWZ0ZXIgY29ycmVjdGluZyBmb3IgYmFja2dyb3VuZCByZXNwaXJhdGlvbjwvc3Bhbj4gYXJlIHNob3duIGluIGdyZXksIGFuZCANCjxzcGFuIHN0eWxlPSJjb2xvcjojNTNhZjhiIj5NT+KCgiBjYWxjdWxhdGlvbnMgYWZ0ZXIgY29ycmVjdGluZyBmb3IgYmFja2dyb3VuZCByZXNwaXJhdGlvbiBhbmQgb3h5Z2VuIGRpZmZ1c2lvbiBkeW5hbWljczwvc3Bhbj4gYXJlIHNob3duIGluIGdyZWVuLg0KDQoNCmBgYHtyLCBmaWcuaGVpZ2h0ID0gOCwgZmlnLndpZHRoPSAxMH0NCiMgRGVmaW5lIHlvdXIgY3VzdG9tIGNvbG91ciBzY2hlbWUNCnBsb3RfY29sb3VycyA8LSBjKCIjZjY5MkI0IiwgIiM2RTc4ODkiLCAiIzUzYWY4YiIpDQoNCiMgQ29sbGVjdCB1bmlxdWUgZmlzaCBJRHMNCmZpc2hfaWRzIDwtIHNsb3BlX2NvcnJfY29tcCAlPiUgDQogIGRwbHlyOjpkaXN0aW5jdChpZCkgJT4lIA0KICBkcGx5cjo6cHVsbChpZCkNCg0KIyBDcmVhdGUgYSBsaXN0IHRvIHN0b3JlIHBsb3RzDQpwbG90X2xpc3QgPC0gbGlzdCgpDQoNCiMgR2VuZXJhdGUgcGxvdHMgYW5kIGFkZCB0aGVtIHRvIHRoZSBsaXN0DQpmb3IgKGlkX2kgaW4gZmlzaF9pZHMpIHsNCiAgcGxvdF9pIDwtIHNsb3BlX2NvcnJfY29tcCAlPiUgDQogICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUgDQogICAgZ2dwbG90KGFlcyh4ID0gRE8sIHkgPSB2YWx1ZSwgY29sb3VyID0gTU8yX3R5cGUpKSArDQogICAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSkgKw0KICAgIHRoZW1lX2NsZWFuKCkgKw0KICAgIGxhYnMoDQogICAgICBzdWJ0aXRsZSA9IGlkX2ksDQogICAgICB4ID0gIkRpc3NvbHZlZCBveHlnZW4gcGVyY2VudGFnZSAoRE8pIiwNCiAgICAgIHkgPSAiTU8yIChPMiBtZy9nL2gpIg0KICAgICkgKw0KICAgIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gcGxvdF9jb2xvdXJzKSArDQogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KICANCiAgcGxvdF9saXN0W1tpZF9pXV0gPC0gcGxvdF9pDQp9DQoNCiMgQ29tYmluZSBwbG90cyBpbiBwYWdlcyBvZiA5ICgzIGNvbHVtbnMgeCAzIHJvd3MpDQpwbG90c19wZXJfcGFnZSA8LSA5DQpuX3BhZ2VzIDwtIGNlaWxpbmcobGVuZ3RoKHBsb3RfbGlzdCkgLyBwbG90c19wZXJfcGFnZSkNCg0KIyBEaXNwbGF5IGVhY2ggcGFnZQ0KZm9yIChpIGluIHNlcV9sZW4obl9wYWdlcykpIHsNCiAgc3RhcnQgPC0gKGkgLSAxKSAqIHBsb3RzX3Blcl9wYWdlICsgMQ0KICBlbmQgPC0gbWluKGkgKiBwbG90c19wZXJfcGFnZSwgbGVuZ3RoKHBsb3RfbGlzdCkpDQogIHBhZ2VfcGxvdHMgPC0gcGF0Y2h3b3JrOjp3cmFwX3Bsb3RzKHBsb3RfbGlzdFtzdGFydDplbmRdLCBuY29sID0gMykNCiAgcHJpbnQocGFnZV9wbG90cykNCn0NCmBgYA0KDQoNCioqRmlndXJlIFMxKio6IEluZGl2aWR1YWwgZmlzaC1sZXZlbCBwbG90cyBzaG93aW5nIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBkaXNzb2x2ZWQgb3h5Z2VuIChETykgcGVyY2VudGFnZSBhbmQgbWV0YWJvbGljIG94eWdlbiBjb25zdW1wdGlvbiByYXRlIChNT+KCgiwgaW4gbWcgT+KCgi9nL2gpIGZvciBlYWNoIDIwLW1pbiBpbnRlcnZhbC4gRWFjaCBwYW5lbCBkaXNwbGF5cyBkYXRhIGZvciBhIHNpbmdsZSBmaXNoIChmaXNoIElEIGluIHRoZSB0b3AgbGVmdCBvZiB0aGUgcGxvdCkuIFBvaW50cyBhcmUgY29sb3VyLWNvZGVkIGJ5IHRoZSB0eXBlIG9mIE1P4oKCIGNhbGN1bGF0aW9uOg0KPHNwYW4gY2xhc3M9InBpbmsiPnJhdyBNT+KCgjwvc3Bhbj4gKHBpbmssICNmNjkyQjQpLA0KPHNwYW4gY2xhc3M9ImdyZXkiPmJhY2tncm91bmQtY29ycmVjdGVkIE1P4oKCPC9zcGFuPiAoZ3JleSwgIzZFNzg4OSksIGFuZA0KPHNwYW4gY2xhc3M9ImdyZWVuIj5mdWxseSBjb3JyZWN0ZWQgTU/igoIgKGFjY291bnRpbmcgZm9yIGJhY2tncm91bmQgcmVzcGlyYXRpb24gYW5kIG94eWdlbiBkaWZmdXNpb24gZHluYW1pY3MpPC9zcGFuPiAoZ3JlZW4sICM1M2FmOGIpLg0KRWFjaCBwb2ludCByZXByZXNlbnRzIGEgbWVhc3VyZW1lbnQgYXQgYSBzcGVjaWZpYyBETyBsZXZlbCwgYW5kIHRoZSBzbGlnaHQgdHJhbnNwYXJlbmN5IChhbHBoYSA9IDAuNSkgaGlnaGxpZ2h0cyBvdmVybGFwcGluZyBvYnNlcnZhdGlvbnMuDQoNCjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT4NCg0KIyDwn5OKIEV4cGxvcmF0b3J5IERhdGEgQW5hbHlzaXMgKEVEQSkNCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQojIyBP4oKCIHZzIE1P4oKCDQoNCiMjIyBGaWd1cmUgUzINCg0KVGhpcyBpbnRlcmFjdGl2ZSB3YXMgdXNlZCB0byBpZGVudGlmeSBhbnkgb3V0bGllcnMsIG9yIHBvdGVudGlhbCBlcnJvcnMuIFRoaXMgaGFzIG5vdCBiZWVuIGdlbmVyYXRlZCBpbiB0aGUgUERGIGBTdXBwbGVtZW50YXJ5IGZpbGUgMWAsIGFzIGl0IGlzIG5vdCBjb21wYXRpYmxlLiANCg0KYGBge3J9DQpsbV9saW5lcyA8LSBzbG9wZV90aWR5ICU+JQ0KICBncm91cF9ieShpZCkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBET19zZXEgPSBsaXN0KHNlcShtaW4oRE8pLCBtYXgoRE8pLCBsZW5ndGgub3V0ID0gMTAwKSksICAjIEdlbmVyYXRlIGEgc2VxdWVuY2Ugb2YgRE8gdmFsdWVzDQogICAgTU8yX3ByZWQgPSBsaXN0KHByZWRpY3QobG0oTU8yX2cgfiBETywgZGF0YSA9IGN1cl9kYXRhKCkpLCBuZXdkYXRhID0gZGF0YS5mcmFtZShETyA9IHNlcShtaW4oRE8pLCBtYXgoRE8pLCBsZW5ndGgub3V0ID0gMTAwKSkpKQ0KICApICU+JQ0KICB1bm5lc3QoYyhET19zZXEsIE1PMl9wcmVkKSkgICMgRXhwYW5kIGxpc3RzIGludG8gcm93cw0KDQojIENyZWF0ZSBzY2F0dGVyIHBsb3Qgd2l0aCBtYXJrZXJzIGZvciBlYWNoIGZpc2gNCnAgPC0gcGxvdF9seSgNCiAgZGF0YSA9IHNsb3BlX3RpZHksDQogIHggPSB+RE8sDQogIHkgPSB+TU8yX2csDQogIHR5cGUgPSAic2NhdHRlciIsDQogIG1vZGUgPSAibWFya2VycyIsDQogIGNvbG9yID0gfmlkLCAgIyBDb2xvdXIgcG9pbnRzIGJ5IGZpc2ggSUQNCiAgbWFya2VyID0gbGlzdChvcGFjaXR5ID0gMC42KSwNCiAgbmFtZSA9IH5pZA0KKQ0KDQojIEFkZCByZWdyZXNzaW9uIGxpbmVzIGZvciBlYWNoIGZpc2gNCnAgPC0gcCAlPiUNCiAgYWRkX3RyYWNlKA0KICAgIGRhdGEgPSBsbV9saW5lcywNCiAgICB4ID0gfkRPX3NlcSwNCiAgICB5ID0gfk1PMl9wcmVkLA0KICAgIHR5cGUgPSAic2NhdHRlciIsDQogICAgbW9kZSA9ICJsaW5lcyIsDQogICAgY29sb3IgPSB+aWQsICAjIEVuc3VyZSBlYWNoIGxpbmUgbWF0Y2hlcyBpdHMgY29ycmVzcG9uZGluZyBmaXNoDQogICAgbGluZSA9IGxpc3Qod2lkdGggPSAxLCBkYXNoID0gInNvbGlkIiksDQogICAgc2hvd2xlZ2VuZCA9IEZBTFNFICAjIEF2b2lkIGNsdXR0ZXJpbmcgdGhlIGxlZ2VuZA0KICApDQoNCiMgRmluYWwgbGF5b3V0DQpwIDwtIHAgJT4lDQogIGxheW91dCgNCiAgICB0aXRsZSA9ICJNTzxzdWI+Mjwvc3ViPiB2cyBEaXNzb2x2ZWQgT3h5Z2VuIHdpdGggaW5kaXZpZHVhbCBsaW5lYXIgcmVncmVzc2lvbnMiLA0KICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICJEaXNzb2x2ZWQgT3h5Z2VuICglKSIpLA0KICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICJNTzxzdWI+Mjwvc3ViPiAobWc8c3VwPi0xPC9zdXA+IE88c3ViPjI8L3N1Yj4gZzxzdXA+LTE8L3N1cD4gaDxzdXA+LTE8L3N1cD4pIiksDQogICAgc2hvd2xlZ2VuZCA9IEZBTFNFDQogICkNCg0KIyBEaXNwbGF5IHBsb3QNCnANCmBgYA0KDQoqKipGaWd1cmUgUzI6KioqIGludGVyYWN0aXZlIHBsb3Qgb2YgbWV0YWJvbGljIHJhdGUgbWVhc3VyZW1lbnRzIChNT+KCgjsgbWcgT+KCgiBnXi0xXmheLTFeKSBieSBkaXNzb2x2ZWQgb3h5Z2VuIHBlcmNlbnRhZ2UgKERPKSBmb3IgYWxsIGZpc2gsIGluY2x1ZGluZyBhbGwgZXN0aW1hdGVzIGR1cmluZyB0aGUgU01SIHBoYXNlIChpLmUuIGludGVybWl0dGVudCBwaGFzZSkuIEluZGl2aWR1YWwgbGluZWFyIHJlZ3Jlc3Npb24gd2VyZSBmaXR0ZWQgZm9yIHZpc3VhbCByZWZlcmVuY2UsIGFuZCBkbyBub3QgcmVwcmVzZW50IHRoZSBiZXN0IGZpdHRpbmcgcmVncmVzc2lvbi4NCg0KIyMjIEZpZ3VyZSBTMw0KDQpMb29raW5nIGF0IHRoZSBkaWZmZXJlbmNlIHJlc3BvbnNlcyBpbiB0aGUgdHdvIHNhbGluaXR5IGdyb3Vwcy4NCg0KYGBge3J9DQpzYWxpbml0eV9zdW1tYXJ5IDwtIHNsb3BlX3RpZHkgJT4lIA0KICBkcGx5cjo6Z3JvdXBfYnkoc2FsaW5pdHlfZ3JvdXApICU+JSANCiAgZHBseXI6OnJlZnJhbWUobiA9IGxlbmd0aCh1bmlxdWUoaWQpKSkNCg0Kc2xvcGVfdGlkeSAlPiUgDQogIGdncGxvdChhZXMoeSA9IE1PMl9nLCB4ID0gRE8sIGNvbG91ciA9IGlkKSkgKyANCiAgZ2VvbV9wb2ludChzaG93LmxlZ2VuZCA9IEZBTFNFKSArDQogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IGlkKSwgbWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSwgY29sb3VyID0gc2NhbGVzOjphbHBoYSgiYmxhY2siLCAwLjUpKSArICMgVHJhbnNwYXJlbnQgYmxhY2sgbGluZXMNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBUUlVFLCBjb2xvdXIgPSAicmVkIikgKyAjIE92ZXJhbGwgc21vb3RoIGxpbmUNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImdhbSIsIGZvcm11bGEgPSB5IH4gcyh4LCBicyA9ICJjcyIpLCBzZSA9IFRSVUUsIGNvbG91ciA9ICJyZWQiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHRoZW1lX2NsZWFuKCkgKw0KICBmYWNldF93cmFwKH5zYWxpbml0eV9ncm91cCkgKw0KICBsYWJzKA0KICAgIHN1YnRpdGxlID0gIm1vMiB2cyBvMiBieSBzYWxpbml0eSB0cmVhdG1lbnQiLA0KICAgIHggPSAiRGlzc29sdmVkIG94eWdlbiBwZXJjZW50YWdlIChETykiLA0KICAgIHkgPSAiTU8yIChPMiBtZy9nL2gpIg0KICApICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBzYWxpbml0eV9zdW1tYXJ5LA0KICAgICAgICAgICAgYWVzKHggPSAtSW5mLCB5ID0gSW5mLCBsYWJlbCA9IHBhc3RlMCgiaXRhbGljKG4pID09ICIsIG4pKSwNCiAgICAgICAgICAgIGhqdXN0ID0gLTAuMSwgdmp1c3QgPSAxLjIsIGluaGVyaXQuYWVzID0gRkFMU0UsIHBhcnNlID0gVFJVRSkNCmBgYA0KDQoqKipGaWd1cmUgUzM6KioqIE1ldGFib2xpYyByYXRlIG1lYXN1cmVtZW50cyAoTU/igoI7IG1nIE/igoIgZ14tMV5oXi0xXikgYnkgZGlzc29sdmVkIG94eWdlbiBwZXJjZW50YWdlIChETykgZm9yIGZpc2ggZnJvbSB0aGUgdHdvIHNhbGluaXR5IHRyZWF0bWVudHMsIGluY2x1ZGluZyBhbGwgZXN0aW1hdGVzIGR1cmluZyB0aGUgU01SIHBoYXNlIChpLmUuIGludGVybWl0dGVudCBwaGFzZSkuIEluZGl2aWR1YWwgbGluZWFyIHJlZ3Jlc3Npb24gd2VyZSBmaXR0ZWQgZm9yIHZpc3VhbCByZWZlcmVuY2UsIGFuZCBkbyBub3QgcmVwcmVzZW50IHRoZSBiZXN0IGZpdHRpbmcgcmVncmVzc2lvbi4gVGhlIHNvbGlkIHJlZCBhbmQgZGFzaGVkIHJlZCBsaW5lIHJlcHJlc2VudHMgdGhlIGdsb2JhbCB0cmVuZCBpbiBlYWNoIG9mIHRoZSB0cmVhdG1lbnRzLCBib3RoIGEgbGluZWFyIChzb2xpZCByZWQpIGFuZCBub24tbGluZWFyIChkYXNoZWQgcmVkOyBHZW5lcmFsaXplZCBBZGRpdGl2ZSBNb2RlbCBmaXR0ZWQgd2l0aCBgZ2VvbV9zbW9vdGhgKS4NCg0KIyMjIEZpZ3VyZSBTNA0KDQpBIHBsb3QgdG8gbG9vayBhdCB0aGUgZGlmZmVyZW50IGNoYW1iZXIgdHlwZXMNCg0KYGBge3J9DQpjaGFtYmVyX3N1bW1hcnkgPC0gc2xvcGVfdGlkeSAlPiUgDQogIGRwbHlyOjpncm91cF9ieShjaGFtYmVyX3R5cGUpICU+JSANCiAgZHBseXI6OnJlZnJhbWUobiA9IGxlbmd0aCh1bmlxdWUoaWQpKSkNCg0Kc2xvcGVfdGlkeSAlPiUgDQogIGdncGxvdChhZXMoeSA9IE1PMl9nLCB4ID0gRE8sIGNvbG91ciA9IGlkKSkgKyANCiAgZ2VvbV9wb2ludChzaG93LmxlZ2VuZCA9IEZBTFNFKSArDQogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IGlkKSwgbWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSwgY29sb3VyID0gc2NhbGVzOjphbHBoYSgiYmxhY2siLCAwLjUpKSArICMgVHJhbnNwYXJlbnQgYmxhY2sgbGluZXMNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBUUlVFLCBjb2xvdXIgPSAicmVkIikgKyAjIE92ZXJhbGwgc21vb3RoIGxpbmUNCiAgZ2VvbV9zbW9vdGgoc2UgPSBUUlVFLCBjb2xvdXIgPSAicmVkIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICB0aGVtZV9jbGVhbigpICsNCiAgZmFjZXRfd3JhcCh+Y2hhbWJlcl90eXBlLCBzY2FsZSA9ICJmcmVlIikgKw0KICBsYWJzKA0KICAgIHN1YnRpdGxlID0gIm1vMiB2cyBvMiBieSBjaGFtYmVyIHR5cGUiLA0KICAgIHggPSAiRGlzc29sdmVkIG94eWdlbiBwZXJjZW50YWdlIChETykiLA0KICAgIHkgPSAiTU8yIChtZyBPMiBnL2gpIg0KICApICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBjaGFtYmVyX3N1bW1hcnksDQogICAgICAgICAgICBhZXMoeCA9IC1JbmYsIHkgPSBJbmYsIGxhYmVsID0gcGFzdGUwKCJpdGFsaWMobikgPT0gIiwgbikpLA0KICAgICAgICAgICAgaGp1c3QgPSAtMC4xLCB2anVzdCA9IDEuMiwgaW5oZXJpdC5hZXMgPSBGQUxTRSwgcGFyc2UgPSBUUlVFKQ0KYGBgDQoNCioqKkZpZ3VyZSBTNDoqKiogTWV0YWJvbGljIHJhdGUgbWVhc3VyZW1lbnRzIChNT+KCgjsgbWcgT+KCgiBnXi0xXmheLTFeKSBieSBkaXNzb2x2ZWQgb3h5Z2VuIHBlcmNlbnRhZ2UgKERPKSBmb3IgZmlzaCB0ZXN0ZWQgaW4gdGhlIDQgZGlmZmVyZW50IGNoYW1iZXIgdHlwZXMsIGluY2x1ZGluZyBhbGwgZXN0aW1hdGVzIGR1cmluZyB0aGUgU01SIHBoYXNlIChpLmUuIGludGVybWl0dGVudCBwaGFzZSkuIEluZGl2aWR1YWwgbGluZWFyIHJlZ3Jlc3Npb24gd2VyZSBmaXR0ZWQgZm9yIHZpc3VhbCByZWZlcmVuY2UsIGFuZCBkbyBub3QgcmVwcmVzZW50IHRoZSBiZXN0IGZpdHRpbmcgcmVncmVzc2lvbi4gVGhlIHNvbGlkIHJlZCBhbmQgZGFzaGVkIHJlZCBsaW5lIHJlcHJlc2VudHMgdGhlIGdsb2JhbCB0cmVuZCBpbiBlYWNoIG9mIHRoZSB0cmVhdG1lbnRzLCBib3RoIGEgbGluZWFyIChzb2xpZCByZWQpIGFuZCBub24tbGluZWFyIChkYXNoZWQgcmVkOyBHZW5lcmFsaXplZCBBZGRpdGl2ZSBNb2RlbCBmaXR0ZWQgd2l0aCBgZ2VvbV9zbW9vdGhgKS4NCg0KDQojIyBSb3V0aW5lIE1P4oKCDQoNCk1ha2luZyBhbiBTTVIgcGhhc2Ugb25seSBkYXRhIGZyYW1lDQoNCmBgYHtyfQ0Kc2xvcGVfdGlkeV9zbXIgPC0gc2xvcGVfdGlkeSAlPiUgDQogIGRwbHlyOjpmaWx0ZXIocGhhc2UgPT0gInNtciIpDQpgYGANCg0KDQpSb3V0aW5lIE1PPHN1Yj4yPC9zdWI+IGJ5IHNhbGluaXR5LiBQbG90IG9mIGFsbCBNTzxzdWI+Mjwvc3ViPiBtZWFzdXJlcyBkdXJpbmcgU01SIHBoYXNlIGJ5IHNhbGluaXR5IHRyZWF0bWVudC4gVGhlIHNtYWxsIHBvaW50cyBhcmUgdGhlIHJhdyBvYnNlcnZlZCB2YWx1ZXMsIHRoZSBzaGFkZWQgYXJlYSBiZWhpbmQgdGhlIHBvaW50cyBpcyB0aGUgYSBrZXJuZWwgZGVuc2l0eSBvZiB0aGUgb2JzZXJ2ZWQgZGF0YSwgdGhlIGJveCBwbG90IHNob3dzIHRoZSBtZWRpYW4gYW5kIGludGVycXVhcnRpbGUgcmFuZ2UgKElRUiksIGFuZCB0aGUgbGFyZ2UgcG9pbnQgc2hvd3MgdGhlIG1lYW4uDQoNCmBgYHtyfQ0KbWVhbl9tbzJfc2FsaW5pdHkgPC0gc2xvcGVfdGlkeV9zbXIgJT4lIA0KICBkcGx5cjo6Z3JvdXBfYnkoc2FsaW5pdHlfZ3JvdXApICU+JSANCiAgZHBseXI6OnJlZnJhbWUobWVhbl9tbzIgPSBtZWFuKE1PMiwgbmEucm0gPSBUUlVFKSkNCg0KZmlnX2kgPC0gZ2dwbG90KCkgKw0KICAgIGdlb21fdmlvbGluKGRhdGEgPSBzbG9wZV90aWR5X3NtciwgYWVzKHggPSBzYWxpbml0eV9ncm91cCwgeSA9IE1PMiwgZmlsbCA9IHNhbGluaXR5X2dyb3VwKSwgY29sb3IgPSBOQSwgYWxwaGEgPSAwLjMpICsNCiAgZ2VvbV9qaXR0ZXIoZGF0YSA9IHNsb3BlX3RpZHlfc21yLCBhZXMoeCA9IHNhbGluaXR5X2dyb3VwLCB5ID0gTU8yLCBmaWxsID0gc2FsaW5pdHlfZ3JvdXApLA0KICAgICAgICAgICAgICAgICAgICAgICBzaGFwZSA9IDIxLCBzaXplID0gMiwgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuMikgKw0KICBnZW9tX2JveHBsb3QoZGF0YSA9IHNsb3BlX3RpZHlfc21yLCBhZXMoeCA9IHNhbGluaXR5X2dyb3VwLCB5ID0gTU8yLCBmaWxsID0gc2FsaW5pdHlfZ3JvdXApLA0KICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IDEsIGFscGhhID0gMC41LCBvdXRsaWVyLnNoYXBlID0gTkEsIHdpZHRoID0gMC4zKSArDQogIGdlb21fcG9pbnQoZGF0YSA9IG1lYW5fbW8yX3NhbGluaXR5LCANCiAgICAgICAgICAgICAgICBhZXMoeCA9IHNhbGluaXR5X2dyb3VwLCB5ID0gbWVhbl9tbzIsIGZpbGwgPSBzYWxpbml0eV9ncm91cCksIA0KICAgICAgICAgICAgICAgIHNpemUgPSAzLCBhbHBoYSA9IDAuOCwgY29sb3VyID0gImJsYWNrIiwgc3Ryb2tlID0gMikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjNEI1MzIwIiwgIiMwMDAwODAiKSkgKyAgIyBDdXN0b20gZmlsbCBjb2xvdXJzDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiIzRCNTMyMCIsICIjMDAwMDgwIikpICsNCiAgdGhlbWVfY2xlYW4oKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KICBsYWJzKA0KICAgIHN1YnRpdGxlID0gIiIsDQogICAgeCA9ICJTYWxpbml0eSBncm91cCAocHB0KSIsDQogICAgeSA9ICJSb3V0aW5lIE1PMiAobWcgTzIgZy9oKSINCiAgKQ0KDQpmaWdfaQ0KYGBgDQoNCg0KIyMgU01SDQoNCkhlcmUncyB0aGUgc2FtZSBwbG90IGJ1dCBmb3Igb25seSB0aGUgU01SLCBhcyBlc3RpbWF0ZWQgd2l0aCBjYWxjU01SIGZ1bmN0aW9uIGJ5IENoYWJvdCwgU3RlZmZlbnNlbiBhbmQgRmFycmVsbCAoMjAxNileWzFdXi4gU3BlY2lmaWNhbGx5LCB3ZSB1c2UgbWVhbiBvZiB0aGUgbG93ZXN0IG5vcm1hbCBkaXN0cmlidXRpb24gKE1MTkQpIHdoZXJlIENWbWxuZCBcPCA1LjQgYW5kIHRoZSBtZWFuIG9mIHRoZSBsb3dlciAyMCUgcXVhbnRpbGUgKHEwLjIpIHdlcmUgQ1ZtbG5kIFw+IDUuNC4gSWYgQ1ZtbG5kIGlzIG5vdCBjYWxjdWxhdGVkIHdlIGhhdmUgdXNlZCBxMC4yLg0KDQpgYGB7cn0NCnNtcl9vbmx5IDwtIHNsb3BlX3RpZHlfc21yICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KGlkKSAlPiUgDQogIGRwbHlyOjpzbGljZSgxKQ0KDQptZWFuX3Ntcl9zYWxpbml0eSA8LSBzbXJfb25seSAlPiUgDQogIGRwbHlyOjpncm91cF9ieShzYWxpbml0eV9ncm91cCkgJT4lIA0KICBkcGx5cjo6cmVmcmFtZShtZWFuX3NtciA9IG1lYW4oU01SLCBuYS5ybSA9IFRSVUUpKQ0KDQpmaWdfaSA8LSBnZ3Bsb3QoKSArDQogICAgZ2VvbV92aW9saW4oZGF0YSA9IHNtcl9vbmx5LCBhZXMoeCA9IHNhbGluaXR5X2dyb3VwLCB5ID0gU01SLCBmaWxsID0gc2FsaW5pdHlfZ3JvdXApLCBjb2xvciA9IE5BLCBhbHBoYSA9IDAuMykgKw0KICBnZW9tX2ppdHRlcihkYXRhID0gc21yX29ubHksIGFlcyh4ID0gc2FsaW5pdHlfZ3JvdXAsIHkgPSBTTVIsIGZpbGwgPSBzYWxpbml0eV9ncm91cCksDQogICAgICAgICAgICAgICAgICAgICAgIHNoYXBlID0gMjEsIHNpemUgPSAyLCBjb2xvciA9ICJibGFjayIsIGFscGhhID0gMC4yKSArDQogIGdlb21fYm94cGxvdChkYXRhID0gc21yX29ubHksIGFlcyh4ID0gc2FsaW5pdHlfZ3JvdXAsIHkgPSBTTVIsIGZpbGwgPSBzYWxpbml0eV9ncm91cCksDQogICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gMSwgYWxwaGEgPSAwLjUsIG91dGxpZXIuc2hhcGUgPSBOQSwgd2lkdGggPSAwLjMpICsNCiAgZ2VvbV9wb2ludChkYXRhID0gbWVhbl9zbXJfc2FsaW5pdHksIA0KICAgICAgICAgICAgICAgIGFlcyh4ID0gc2FsaW5pdHlfZ3JvdXAsIHkgPSBtZWFuX3NtciwgZmlsbCA9IHNhbGluaXR5X2dyb3VwKSwgDQogICAgICAgICAgICAgICAgc2l6ZSA9IDMsIGFscGhhID0gMC44LCBjb2xvdXIgPSAiYmxhY2siLCBzdHJva2UgPSAyKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiM0QjUzMjAiLCAiIzAwMDA4MCIpKSArICAjIEN1c3RvbSBmaWxsIGNvbG91cnMNCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCIjNEI1MzIwIiwgIiMwMDAwODAiKSkgKw0KICB0aGVtZV9jbGVhbigpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogIGxhYnMoDQogICAgc3VidGl0bGUgPSAiIiwNCiAgICB4ID0gIlNhbGluaXR5IGdyb3VwIChwcHQpIiwNCiAgICB5ID0gIk1PMiAobWcgTzIgZy9oKSINCiAgKQ0KDQpmaWdfaQ0KYGBgDQoNCiMjIEluZGl2aWR1YWwgT+KCgiwgTU/igoIsIGFuZCBTTVINCg0KSGVyZSB3ZSB3aWxsIHBsb3QgdGhlIGluZGl2aWR1YWwgcmVsYXRpb25zaGlwIGJldHdlZW4gT+KCgiwgTU/igoIsIGFuZCBTTVIgZm9yIGFsbCBmaXNoDQoNCkNyZWF0ZSBvdXRwdXQgZGlyZWN0b3J5IGlmIG5lZWRlZA0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCiMgQ3JlYXRlIG91dHB1dCBkaXJlY3RvcnkgaWYgbmVlZGVkDQpvdXRwdXRfZmlnX3Nsb3Blc193ZCA8LSBmaWxlLnBhdGgob3V0cHV0X2ZpZ193ZCwgInNsb3BlcyIpDQppZiAoIWRpci5leGlzdHMob3V0cHV0X2ZpZ19zbG9wZXNfd2QpKSB7DQogIGRpci5jcmVhdGUob3V0cHV0X2ZpZ19zbG9wZXNfd2QpDQp9DQpgYGANCg0KTG9vcCB0aHJvdWdoIGVhY2ggZmlzaCBJRCB0byBjcmVhdGUgYSBwbG90LCBzYXZlIHRoZXNlIHRvIGEgc2luZ2xlIFBERiBmaWxlLCB0aGlzIGlzIGNhbGxlZCBgY29tYmluZWRfc2xvcGVzLnBkZmAuIEl0IGNhbiBiZSBmb3VuZCBpbiB0aGlzIHBhdGggYG91dHB1dC1maWcvc2xvcGVzL2NvbWJpbmVkX3Nsb3Blcy5wZGZgIA0KVGhlc2UgcGxvdHMgc2hvdyBNZXRhYm9saWMgcmF0ZSBtZWFzdXJlbWVudHMgKE1P4oKCOyBtZyBP4oKCIGdeLTFeaF4tMV4gYnkgTzxzdWI+Mjwvc3ViPikgYXQgZWFjaCBvZiB0aGUgZm91ciBleHBlcmltZW50YWwgcGhhc2UgKHRoZSBvdmVyIG5pZ2h0IFNNUiBpbnRlcm1pdHRlbnQtZmxvdyByZXNwaXJvbWV0cnkgcGhhc2UsIGNsb3NlZCBwaGFzZXMgYXQgNTAlLCA3NSUgb3IgMTAwJSBPPHN1Yj4yPC9zdWI+KS4gVGhlIGVzdGltYXRlZCBTTVIgdmFsdWUgaXMgcmVwcmVzZW50ZWQgYXMgYSBkYXNoZWQgcmVkIGxpbmUuDQoNCmBgYHtyLCBmaWcuaGVpZ2h0ID0gMywgZmlnLndpZHRoPSA0fQ0KIyBEZWZpbmUgY29uc2lzdGVudCBjb2xvcnMgZm9yIGFsbCBwaGFzZXMNCnBoYXNlX2NvbG9ycyA8LSBjKA0KICAiNTBjIiAgPSAiI2U1NmI2ZiIsDQogICI3NWMiICA9ICIjYjU2NTc2IiwNCiAgIjEwMGMiID0gIiM2ZDU5N2EiLA0KICAic21yIiAgPSAiIzM1NTA3MCINCikNCg0KaWRzIDwtIHNsb3BlX3RpZHkgJT4lDQogIGRwbHlyOjpkaXN0aW5jdChpZCkgJT4lDQogIHB1bGwoaWQpICU+JQ0KICBhcy5saXN0KCkNCg0KTU8yX3Bsb3RfbGlzdCA8LSBsaXN0KCkNCg0KIyAxKSBPcGVuIHRoZSBQREYgZGV2aWNlIG9uY2UNCnBkZigNCiAgZmlsZSAgID0gZmlsZS5wYXRoKG91dHB1dF9maWdfc2xvcGVzX3dkLCAiY29tYmluZWRfc2xvcGVzLnBkZiIpLA0KICB3aWR0aCAgPSA4LA0KICBoZWlnaHQgPSA2DQopDQoNCiMgMikgTG9vcCBvdmVyIElEcyBhbmQgY3JlYXRlIGVhY2ggcGxvdA0KZm9yIChpZF9pIGluIGlkcykgew0KDQogIHNtciA8LSBzbG9wZV90aWR5ICU+JQ0KICAgIGRwbHlyOjpmaWx0ZXIoaWQgPT0gaWRfaSkgJT4lDQogICAgZHBseXI6OnNsaWNlKDEpICU+JQ0KICAgIGRwbHlyOjpwdWxsKFNNUikNCg0KICBwbG90IDwtIHNsb3BlX3RpZHkgJT4lDQogICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUNCiAgICBnZ3Bsb3QoYWVzKHggPSBvMiwgeSA9IE1PMikpICsNCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBzbXIsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gImRhcmtyZWQiKSArDQogICAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gcGhhc2UpKSArDQogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHBoYXNlX2NvbG9ycywgZHJvcCA9IEZBTFNFKSArICAjIEVuc3VyZXMgY29uc2lzdGVudCBjb2xvdXJzDQogICAgdGhlbWVfY2xlYW4oKSArDQogICAgbGFicygNCiAgICAgIHN1YnRpdGxlID0gcGFzdGUwKGlkX2ksICIgc2xvcGVzIiksDQogICAgICB4ID0gIk1lYW4gbzIgKG1nX3Blcl9sKSIsDQogICAgICB5ID0gImFicyhtbzIpIChtZ19wZXJfbCkiDQogICAgKQ0KDQogICMgSW5zdGVhZCBvZiBzYXZpbmcgZWFjaCBwbG90IHNlcGFyYXRlbHksIGp1c3QgcHJpbnQgaXQNCiAgcHJpbnQocGxvdCkNCg0KICBNTzJfcGxvdF9saXN0W1tpZF9pXV0gPC0gcGxvdA0KfQ0KDQojIDMpIENsb3NlIHRoZSBQREYgZGV2aWNlICphZnRlciogdGhlIGxvb3ANCmRldi5vZmYoKQ0KYGBgDQoNCjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT4NCg0KIyDwn6euIEFuYWx5c2lzDQoNCjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT4NCg0KIyMgUm91dGluZSBNTzINCg0KIyMjIFNjYWxpbmcgcHJlZGljdG9ycw0KDQpIZXJlIHdlIHNjYWxlIG91ciBwcmVkaWN0b3JzIGZvciB0aGUgbW9kZWwuIFdlIGhhdmUgZmlyc3QgYXBwbGllZCBhbiBsb2cgdHJhbnNmb3JtYXRpb24gdG8gbWFzcywgc28gaXRzIGRpcmVjdGx5IGludGVycHJldGFibGUgYXMgdGhlIG1hc3Mtc2NhbGluZyBleHBvbmVudCwganVzdCBsaWtlIGluIG1ldGFib2xpYyB0aGVvcnkuDQoNCmBgYHtyfQ0Kc2NhbGVfbGlzdCA8LSBjKCJ0ZW1wIiwgIm9yZGVyIiwgImxvZ19tYXNzIikgDQoNCnNsb3BlX3RpZHlfc21yIDwtIHNsb3BlX3RpZHlfc21yICU+JQ0KICBkcGx5cjo6bXV0YXRlKGxvZ19tYXNzID0gbG9nKG1hc3MpLA0KICAgICAgICAgICAgICAgIGFjcm9zcyhhbGxfb2Yoc2NhbGVfbGlzdCksIH4gc2NhbGUoLngsIGNlbnRlciA9IFRSVUUsIHNjYWxlID0gRkFMU0UpLA0KICAgICAgICAgICAgICAgICAgICAgICAubmFtZXMgPSAiey5jb2x9X2MiKSwNCiAgICAgICAgICAgICAgICBsaWdodF9kYXJrX2MgPSBpZl9lbHNlKGxpZ2h0X2RhcmsgPT0gImxpZ2h0IiwgMC41LCAtMC41KSkNCmBgYA0KDQpTdW1tYXJ5IG9mIHByZWRpY3RvcnMgdXNlZCBpbiB0aGUgbW9kZWwgYmVsb3cNCg0KYGBge3J9DQpzbG9wZV90aWR5X3NtciAlPiUNCiAgZHBseXI6Om11dGF0ZShjeWNsZSA9IGFzLm51bWVyaWMoY3ljbGUpKSAlPiUgDQogIGRwbHlyOjpyZWZyYW1lKHRlbXBfcmFuZ2UgPSBwYXN0ZTAocm91bmQobWluKHRlbXAsIG5hLnJtID0gVFJVRSksMiksICLigJMiLCByb3VuZChtYXgodGVtcCwgbmEucm0gPSBUUlVFKSwyKSksDQogICAgICAgICAgICBtYXNzX3JhbmdlID0gcGFzdGUwKHJvdW5kKG1pbihtYXNzLCBuYS5ybSA9IFRSVUUpLDIpLCAi4oCTIiwgcm91bmQobWF4KG1hc3MsIG5hLnJtID0gVFJVRSksMikpLA0KICAgICAgICAgIGN5Y2xlX3JhbmdlID0gcGFzdGUwKHJvdW5kKG1pbihjeWNsZSwgbmEucm0gPSBUUlVFKSwyKSwgIuKAkyIsIHJvdW5kKG1heChjeWNsZSwgbmEucm0gPSBUUlVFKSwyKSksDQogICAgICAgICAgbnVtYmVyX2Zpc2ggPSBsZW5ndGgodW5pcXVlKGlkKSkgIA0KICAgICAgICAgICkgJT4lIA0KICBndCgpDQpgYGANCg0KIyMjIE1vZGVsIHN0cnVjdHVyZQ0KDQpIZXJlIHdlIHdpbGwgdXNlIGEgQmF5ZXNpYW4gR2VuZXJhbGlzZWQgTGluZWFyIE1peGVkIE1vZGVsIChHTE1NKSB3aXRoIGEgR2FtbWEgZGlzdHJpYnV0aW9uIGFuZCBhIGxvZyBsaW5rLCB3aGVyZSB0aGUgc2hhcGUgcGFyYW1ldGVyICjOsSkgaXMgYWxzbyBtb2RlbGxlZCBhcyBhIGZ1bmN0aW9uIG9mIHByZWRpY3RvcnMuIFRoaXMgbW9kZWxzIE1PPHN1Yj4yPC9zdWI+IGJ5IHNhbGluaXR5IGR1cmluZyB0aGUgU01SIHBoYXNlIHRvIHNlZSBpZiB0aGUgZmlzaCBoZWxkIGF0IGRpZmZlcmVudCBzYWxpbml0aWVzIGhhdmUgZGlmZmVyZW50IFJNUnMuIFdlIGhhdmUgYWxzbyBhZGRlZCBhIGZldyBzY2FsZWQgcHJlZGljdG9ycywgdGhhdCBtYXkgaGVscCBkZXNjcmliZSB2YXJpYXRpb24gaW4gdGhlIGRhdGEsIHN1Y2ggYXMgbWFzcyAoZzsgMC4yMS0tMS42KSB0ZW1wZXJhdHVyZSAowrBDOyAxMy44NC0tMTQuMzgpLCBjeWNsZSBvcmRlciAoNS0tMjcpLCBhbmQgbGlnaHQvZGFyayBjeWNsZSAobGlnaHQgb3IgZGFyazsgbGlnaHQgYmV0d2VlbiAwNzowMDowMCBhbmQgMTk6MDA6MDApLCB3ZSBhbHNvIGluY2x1ZGUgYSByYW5kb20gZWZmZWN0IGZvciBmaXNoIGlkIHRvIGFjY291bnQgZm9yIG11bHRpcGxlIE1PPHN1Yj4yPC9zdWI+IG1lYXN1cmVzIG9uIGVhY2ggZmlzaCAoMS0tNTgpLiBXZSBhbGxvd2VkIHRoZSB0aGUgc2hhcGUgcGFyYW1ldGVyICjOsSkgdG8gdmFyeSBhcyBhIGZ1bmN0aW9uIG9mIHNvbWUgb2YgdGhlIHByZWRpY3RvcnMgKGUuZy4gc2FsaW5pdHlfZ3JvdXAsIG9yZGVyX3opIHRvIGltcHJvdmUgZml0Lg0KDQpgYGB7cn0NCm1vMl9nYW1tYV9iZiA8LSBiZihNTzIgfiB0ZW1wX2MgKyANCiAgICAgICAgICAgICAgICAgICAgIG9yZGVyX2MgICsgDQogICAgICAgICAgICAgICAgICAgICBsaWdodF9kYXJrX2MgKyANCiAgICAgICAgICAgICAgICAgICAgIGxvZ19tYXNzX2MgKyANCiAgICAgICAgICAgICAgICAgICAgIHNhbGluaXR5X2dyb3VwICsgKDF8aWQpLA0KICAgICAgICAgICAgICAgICAgIHNoYXBlIH4gc2FsaW5pdHlfZ3JvdXAgKyANCiAgICAgICAgICAgICAgICAgICAgIG9yZGVyX2MsDQogICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gR2FtbWEobGluayA9ICJsb2ciKSkNCmBgYA0KDQojIyMgUHJpb3Igc2VsZWN0aW9uDQoNClRoZXNlIGFyZSB0aGUgZGVmYXVsdCBwcmlvcnMuIFdlIHdpbGwgdXNlIHRoZXNlLg0KDQpgYGB7cn0NCmRlZmF1bHRfcHJpb3IgPC0gZ2V0X3ByaW9yKG1vMl9nYW1tYV9iZiwgZGF0YSA9IHNsb3BlX3RpZHlfc21yLCBmYW1pbHkgPSBHYW1tYShsaW5rID0gImxvZyIpKQ0KZGVmYXVsdF9wcmlvciAlPiUgDQogIGd0KCkNCmBgYA0KDQojIyMgUnVuIG1vZGVsDQoNCkhlcmUgd2UgcnVuIHRoZSBtb2RlbCwgSSBoYXZlIGhhc2hlZCB0aGlzIG91dCBiZWNhdXNlIEkgaGF2ZSBzYXZlZCB0aGUgbW9kZWwgZm9yIHF1aWNrIHJlbG9hZGluZy4NCg0K4o+t77iPICoqU2tpcCB0aGlzIHN0ZXAqKiBpZiB5b3UgaGF2ZSBkb3dubG9hZGVkIHRoZSBzYXZlZCBtb2RlbCBgbW8yX21vZF9nYW1tYS5yZHNgIGZyb20gR2l0SHViIChvciBwdWxsZWQgdGhlIGVudGlyZSBHaXRIdWIgcHJvamVjdCkNCg0KYGBge3IsIGVjaG89RkFMU0V9DQojIG1vMl9tb2RfZ2FtbWEgPC0gYnJtKG1vMl9nYW1tYV9iZiwNCiMgICAgICAgICAgICAgICAgZGF0YSA9IHNsb3BlX3RpZHlfc21yLA0KIyAgICAgICAgICAgICAgICBjb3JlcyA9IDQsDQojICAgICAgICAgICAgICAgIGNoYWlucyA9IDQsDQojICAgICAgICAgICAgICAgIHByaW9yID0gZGVmYXVsdF9wcmlvciwNCiMgICAgICAgICAgICAgICAgd2FybXVwID0gMTAwMCwNCiMgICAgICAgICAgICAgICAgc2VlZCA9IDE0MzAxOSwNCiMgICAgICAgICAgICAgICAgdGhpbiA9IDIsDQojICAgICAgICAgICAgICAgIGl0ZXIgPSA4MDAwLA0KIyAgICAgICAgICAgICAgICBzYXZlX3BhcnMgPSBzYXZlX3BhcnMoYWxsPVRSVUUpLA0KIyAgICAgICAgICAgICAgICBzYW1wbGVfcHJpb3IgPSBUUlVFLA0KIyAgICAgICAgICAgICAgICBmaWxlID0gcGFzdGUwKG91dHB1dF9tb2RzX3dkLCAnLi9tbzJfbW9kX2dhbW1hJykpDQojIHByaW50KCJNb2RlbCBjb21wbGV0ZSIpDQpgYGANCg0KSGVyZSB3ZSByZWxvYWQgdGhlIG1vZGVsDQoNCmBgYHtyfQ0KbW8yX21vZF9nYW1tYSA8LSAgcmVhZFJEUyhmaWxlID0gcGFzdGUwKG91dHB1dF9tb2RzX3dkLCAnLi9tbzJfbW9kX2dhbW1hLnJkcycpKQ0KYGBgDQoNCiMjIyBNb2RlbCBkaWFnbm9zdGljcw0KDQpDaGVja2luZyBtb2RlbCBjb252ZXJnZW5jZQ0KDQpgYGB7cn0NCmNvbG9yX3NjaGVtZV9zZXQoInJlZCIpDQpwbG90KG1vMl9tb2RfZ2FtbWEsIGFzayA9IEYpDQpgYGANCg0KQ2hlY2tpbmcgcmhhdCBhcmUgZXF1YWwgdG8gb25lDQoNCmBgYHtyfQ0Kc3VtbWFyeShtbzJfbW9kX2dhbW1hKQ0KYGBgDQoNClVzaW5nIGxlYXZlIG9uZSBvdXQgKGxvbykgbWVhc3VyZSBvZiBmaXQsIHRoZSBtb2RlbCBhcHBlYXJzIHRvIHByZWZvcm0gd2VsbCwgYWxsLCBidXQgb25lIFBhcmV0byBrIGVzdGltYXRlcyBhcmUgZ29vZCAoayBcPCAwLjcpDQoNCmBgYHtyfQ0KbG9vKG1vMl9tb2RfZ2FtbWEpDQpgYGANCg0KTW9kZWwgcHJlZGljdGlvbnMgZ2VuZXJhbGx5IGFsaWduIHdpdGggdGhlIG9ic2VydmVkIGRhdGENCg0KYGBge3J9DQpjb2xvcl9zY2hlbWVfc2V0KCJyZWQiKQ0KcCA8LSBwcF9jaGVjayhtbzJfbW9kX2dhbW1hLCB0eXBlID0gImRlbnNfb3ZlcmxheSIpDQpwDQpgYGANCg0KIyMjIPCfk4ggUmVzdWx0cw0KDQpXZSBkaWQgbm90IHNlZSBhIG1lYW5pbmdmdWwgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSByb3V0aW5lIG1ldGFib2xpYyByYXRlIGZvciBmaXNoIGZyb20gdGhlIHR3byBzYWxpbml0eSB0cmVhdG1lbnRzLg0KDQojIyMjIFRhYmxlIFMxDQoNCioqVGFibGUgUzEqKjogRml4ZWQgZWZmZWN0IEVzdGltYXRlcyAozrIpIGFuZCA5NSUgQ3JlZGlibGUgSW50ZXJ2YWxzICg5NSUgQ0kpDQoNCmBgYHtyfQ0KbW9kZWxfZXN0IDwtIGZpeGVmKG1vMl9tb2RfZ2FtbWEsIHByb2JzID0gYygwLjAyNSwgMC45NzUpKSAlPiUgDQogIGFzLmRhdGEuZnJhbWUoKSAlPiUgDQogIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKHZhciA9ICJQcmVkaWN0b3IiKSAlPiUgDQogIGRwbHlyOjptdXRhdGUoJ86yJyA9IHJvdW5kKEVzdGltYXRlLCAzKSwNCiAgICAgICAgICAgICAgICBRMi41ID0gcm91bmQoUTIuNSwgMyksDQogICAgICAgICAgICAgICAgUTk3LjUgPSByb3VuZChROTcuNSwgMyksDQogICAgICAgICAgICAgICAgJzk1JSBDSScgPSBwYXN0ZTAoIlsiLCBRMi41LCAiLCAiLCBROTcuNSwgIl0iKSkNCg0KbW9kZWxfZXN0ICU+JSANCiAgZHBseXI6OnNlbGVjdChQcmVkaWN0b3IsICfOsicsICc5NSUgQ0knKSAlPiUgDQogIGd0KCkNCmBgYA0KDQpMb29raW5nIGF0IHRoZSBtYXJnaW5hbCBtZWFuIE1PMiBmb3IgZWFjaCBzYWxpbml0eSB0cmVhdG1lbnQNCg0KYGBge3J9DQplbV9yZXN1bHRzIDwtIGVtbWVhbnMobW8yX21vZF9nYW1tYSwgfiBzYWxpbml0eV9ncm91cCkgDQoNCmVtX3Jlc3VsdHNfZGYgPC0gZW1fcmVzdWx0cyAlPiUNCiAgYXMuZGF0YS5mcmFtZSgpICU+JQ0KICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IHJvdW5kKGV4cCguKSwzKSkpDQoNCmVtX3Jlc3VsdHNfZGYgJT4lIA0KICBndCgpDQpgYGANCg0KVGhlc2UgYXJlIHRoZSBlc3RpbWF0ZWQgbWVhbiBjb25zdHJhc3QsIHdlIGhhdmUgZXhwb25lbnRpYXRlZCB0aGUgbG9nIGVzdGltYXRlIHRvIGdldCB0aGUgZm9sZC1jaGFuZ2UuIFRoaXMgbWVhbnMgdGhlIG1vZGVsIHByZWRpY3RzIHRoYXQgc2FpbGlhbnR5IGdyb3VwIDAgaGFzIFx+MTIlIGhpZ2hlciBtZXRhYm9saWMgcmF0ZSB0aGFuIGdyb3VwIDkgKDEuMTIpLS0tYnV0IHRoaXMgZGlmZmVyZW5jZSBpcyBub3QgY3JlZGlibGUsIGJlY2F1c2UgdGhlIGludGVydmFsIGZvciB0aGF0IGRpZmZlcmVuY2UgaW5jbHVkZXMgbm8gZGlmZmVyZW5jZSAoaS5lLiBhIHJhdGlvIG9mIDEuMCkuDQoNCmBgYHtyfQ0KY29udHJhc3RfcmVzdWx0cyA8LSBjb250cmFzdChlbV9yZXN1bHRzLCBtZXRob2QgPSAicGFpcndpc2UiKQ0KDQpjb250cmFzdF9yZXN1bHRzX2RmIDwtICBjb250cmFzdF9yZXN1bHRzICU+JSANCiAgYXMuZGF0YS5mcmFtZSgpICU+JQ0KICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IHJvdW5kKGV4cCguKSwyKSkpDQoNCmNvbnRyYXN0X3Jlc3VsdHNfZGYgJT4lIA0KICBndCgpDQpgYGANCg0KRUVNIGNvbnRyYXN0cyBmb3IgdGhlIHR3byBsaWdodCBwaGFzZXMsIHdoZXJlIC0wLjUgaXMgZGFyaywgYW5kIDAuNSBpcyBsaWdodA0KDQpgYGB7cn0NCmVtX3Jlc3VsdHMgPC0gZW1tZWFucyhtbzJfbW9kX2dhbW1hLCB+IGxpZ2h0X2RhcmtfYywNCiAgICAgICAgICAgICAgICAgICAgICAgYXQgPSBsaXN0KGxpZ2h0X2RhcmtfYyA9IGMoMC41LCAtMC41KSkpDQoNCmNvbnRyYXN0X3Jlc3VsdHMgPC0gY29udHJhc3QoZW1fcmVzdWx0cywgbWV0aG9kID0gInBhaXJ3aXNlIiwgLnJldiA9IFRSVUUpDQoNCmNvbnRyYXN0X3Jlc3VsdHNfZGYgPC0gIGNvbnRyYXN0X3Jlc3VsdHMgJT4lIA0KICBhcy5kYXRhLmZyYW1lKCkgJT4lDQogIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIH4gcm91bmQoZXhwKC4pLDIpKSkNCg0KY29udHJhc3RfcmVzdWx0c19kZiAlPiUgDQogIGd0KCkNCmBgYA0KDQpIZXJlIHdlIHdlIGNhbGN1bGF0ZSB0aGUgbW9kZWwtZXN0aW1hdGVkIG1hcmdpbmFsIG1lYW5zIGZvciBNTzIgZm9yIGEgdW5pdCBpbmNyZWFzZSBpbiBtYXNzIGFuZCB0cmFuc2Zvcm0gdGhpcyBvbnRvIGEgZm9sZC1jaGFuZ2Ugc2NhbGUuIFdoZXJlIGxvZyhtYXNzKSBoYXMgYmUgY2VudGVyZWQsIGEgdmF1bGUgb2YgMCByZXByZXNlbnRzIHRoZSBtZWFuIG1hc3Mgb2YgZmlzaCwgYW5kIDEgY29ycmVzcG9uZHMgdG8gYSBmaXNoIHdpdGggbG9nKG1hc3MpID0gMSB1bml0IGFib3ZlIHRoZSBtZWFuIChpLmUuIDIuNyB0aW1lcyBsYXJnZSkuDQoNCmxvZyhtYXNzPHN1Yj4yPC9zdWI+KSA9IGxvZyhtYXNzPHN1Yj4xPC9zdWI+KSsxDQoNCklmIHlvdSBleHBvbmVudGlhdGUgYm90aCBzaWRlczoNCg0KbWFzczxzdWI+Mjwvc3ViPiA9IG1hc3M8c3ViPjE8L3N1Yj4geCBleHAoMSkNCg0KbWFzczxzdWI+Mjwvc3ViPiDiiYggbWFzczxzdWI+MTwvc3ViPiB4IDIuNzE4DQoNCmBgYHtyfQ0KZW1fbWFzcyA8LSBlbW1lYW5zKG1vMl9tb2RfZ2FtbWEsIH4gbG9nX21hc3NfYywgYXQgPSBsaXN0KGxvZ19tYXNzX2MgPSBjKDAsIDEpKSkNCg0KIyBHZXQgdGhlIGNvbnRyYXN0IChkaWZmZXJlbmNlIGluIGxvZyBNT+KCgiksIHRoZW4gYmFjay10cmFuc2Zvcm0NCmNvbnRyYXN0KGVtX21hc3MsIG1ldGhvZCA9ICJyZXZwYWlyd2lzZSIpICU+JQ0KICBhcy5kYXRhLmZyYW1lKCkgJT4lDQogIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIGV4cCkpICU+JQ0KICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IHJvdW5kKC4sIDIpKSkgJT4lDQogIGd0KCkNCmBgYA0KDQpQdWxsaW5nIHRoZSBlbW1lYW5zIGRyYXdzIGZvciBvdXIgcGxvdA0KDQpgYGB7cn0NCmVtbWVhbnNfZHJhd3Nfcm1yIDwtIG1vMl9tb2RfZ2FtbWEgJT4lDQogIGVtbWVhbnMofiBzYWxpbml0eV9ncm91cCkgJT4lDQogIGdhdGhlcl9lbW1lYW5zX2RyYXdzKCkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKC52YWx1ZSA9ICBleHAoLnZhbHVlKSwNCiAgICAgICAgICAgICAgICBzYWxpbml0eV9ncm91cCA9IGFzLmNoYXJhY3RlcihzYWxpbml0eV9ncm91cCkpDQoNCmVtbWVhbnNfY29udHJhc3RfZHJhd3Nfcm1yICA8LSAgbW8yX21vZF9nYW1tYSAlPiUNCiAgZW1tZWFucyh+IHNhbGluaXR5X2dyb3VwKSAlPiUNCiAgY29udHJhc3QobWV0aG9kID0gInBhaXJ3aXNlIikgJT4lDQogIGdhdGhlcl9lbW1lYW5zX2RyYXdzKCkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKC52YWx1ZSA9ICBleHAoLnZhbHVlKSkNCmBgYA0KDQojIyMjIEZpZ3VyZSAxYQ0KDQoqKipOT1RFOiBUaGlzIHBsb3QgaXMgaW4gdGhlIG1haW4gdGV4dCBvZiB0aGUgbWFudXNjcmlwdCwgd2hpY2ggaXMgd2F5IGl0IGlzIGNhbGxlZCBGaWd1cmUgMWEgKG5vdCBGaWd1cmUgU2kpKioqDQoNCmBgYHtyfQ0KZmlnXzFhIDwtIGdncGxvdCgpICsNCiAgZ2VvbV92aW9saW4oZGF0YSA9IHNsb3BlX3RpZHlfc21yLA0KICAgICAgICAgICAgICBhZXMoeCA9IHNhbGluaXR5X2dyb3VwLCB5ID0gTU8yLCBmaWxsID0gc2FsaW5pdHlfZ3JvdXApLA0KICAgICAgICAgICAgICBjb2xvciA9IE5BLCBhbHBoYSA9IDAuMikgKw0KICBnZW9tX2ppdHRlcihkYXRhID0gc2xvcGVfdGlkeV9zbXIsDQogICAgICAgICAgICAgIGFlcyh4ID0gc2FsaW5pdHlfZ3JvdXAsIHkgPSBNTzIsIGZpbGwgPSBzYWxpbml0eV9ncm91cCksDQogICAgICAgICAgICAgIHNoYXBlID0gMjEsIHdpZHRoID0gMC4zLCBzaXplID0gMSwgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuMSkgKw0KICBnZW9tX3BvaW50KGRhdGEgPSBtZWFuX21vMl9zYWxpbml0eSwNCiAgICAgICAgICAgICBhZXMoeCA9IHNhbGluaXR5X2dyb3VwLCB5ID0gbWVhbl9tbzIsIGZpbGwgPSBzYWxpbml0eV9ncm91cCksDQogICAgICAgICAgICAgc2l6ZSA9IDQsIGFscGhhID0gMSwgc3Ryb2tlID0gMiwgY29sb3IgPSAiYmxhY2siLCBzaGFwZSA9IDIxLA0KICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fbnVkZ2UoeCA9IDAuMDUpKSArDQogIHN0YXRfcG9pbnRpbnRlcnZhbChkYXRhID0gZW1tZWFuc19kcmF3c19ybXIsIA0KICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBzYWxpbml0eV9ncm91cCwgeSA9IC52YWx1ZSksDQogICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAiZ3JleSIsIHBvaW50X2ludGVydmFsID0gIm1lYW5fcWkiLCAud2lkdGggPSAwLjk1LCBzaGFwZSA9IDIxLCAgc3Ryb2tlID0gMiwgcG9pbnRfc2l6ZSA9IDQsIGFscGhhID0gMSwNCiAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fbnVkZ2UoeCA9IC0wLjA1KSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLjAwLCAwLjM1KSkgKyAgIyDwn5GIIFNldCB5LWF4aXMgcmFuZ2UgaGVyZQ0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjNEI1MzIwIiwgIiMwMDAwODAiKSkgKw0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoIiM0QjUzMjAiLCAiIzAwMDA4MCIpKSArDQogIHRoZW1lKA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGNvbG91ciA9ICJibGFjayIsIGZpbGwgPSBOQSwgbGluZXdpZHRoID0gMSksDQogICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIiwgY29sb3VyID0gTkEpLA0KICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIiwgY29sb3VyID0gTkEpDQogICkgKw0KICBsYWJzKA0KICAgIHN1YnRpdGxlID0gIiIsDQogICAgeCA9ICJTYWxpbml0eSBncm91cCAocHB0KSIsDQogICAgeSA9ICJSb3V0aW5lIE1PMiAobWcgTzIgZy9oKSINCiAgKQ0KDQpmaWdfMWENCmBgYA0KDQoqKkZpZ3VyZSAxYToqKiBSb3V0aW5lIG1ldGFib2xpYyByYXRlIChpLmUuIE1PPHN1Yj4yPC9zdWI+IChtZ14tMV4gTzxzdWI+Mjwvc3ViPiBoXi0xXikgbWVhc3VyZWQgZHVyaW5nIFNNUiBtZWFzc3VybWVudHMpIHBsb3R0ZWQgYnkgc2FsaW5pdHkgdHJlYXRtZW50LiBUaGUgc21hbGwgdHJhbnNwYXJlbnQgcG9pbnRzIGFyZSB0aGUgb2JzZXJ2ZWQgdmFsdWVzLCB0aGUgc2hhZGVkIGFyZWEgYmVoaW5kIHRoZSBwb2ludHMgaXMgdGhlIGEga2VybmVsIGRlbnNpdHkgb2YgdGhlIG9ic2VydmVkIGRhdGEsIHRoZSBsYXJnZSBjb2xvdXJlZCBwb2ludCAodG8gdGhlIHJpZ2h0KSBpcyB0aGUgb2JzZXJ2ZWQgbWVhbiwgdGhlIGxhcmdlIGdyZXkgcG9pbnQgd2l0aCBlcnJvciBiYXJzICh0byB0aGUgbGVmdCkgaXMgdGhlIG1vZGVsIGVzdGltYXRlZCBtYXJnaW5hbCBtZWFuIChlZW1lYW4pIDk1JSBDcmVkaWJsZSBJbnRlcnZhbHMgKDk1JSBDSSkuDQoNCmBgYHtyfQ0KIyBnZ3NhdmUoZmlsZW5hbWUgPSBwYXN0ZTAob3V0cHV0X2ZpZ193ZCwgIi4vbXNfZmlndXJlcy4vZmlndXJlLTFhLnBkZiIpLA0KIyAgICAgICAgcGxvdCA9IGZpZ18xYSwNCiMgICAgICAgIHdpZHRoID0gMjEwLzIsDQojICAgICAgICBoZWlnaHQgPSAyOTcvMiwgICMgU3BlY2lmeSB0aGUgaGVpZ2h0IG9mIHRoZSBwbG90DQojICAgICAgICB1bml0cyA9ICJtbSIpDQpgYGANCg0KDQpUaGVyZSB3YXMgbW9kZXJhdGUgYnV0IG1lYW5pbmdmdWwgdmFyaWF0aW9uIGluIFJNUiBiZXR3ZWVuIGluZGl2aWR1YWxzLCBldmVuIGFmdGVyIGFjY291bnRpbmcgZm9yIG1hc3MsIHRlbXBlcmF0dXJlLCBzYWxpbml0eSwgYW5kIGxpZ2h0IHBoYXNlLiBUaGUgZXN0aW1hdGVkIHN0YW5kYXJkIGRldmlhdGlvbiBvZiBpbmRpdmlkdWFsIFJNUiB3YXMgMC4zMSBbMC4yNiB0byAwLjM4XSwgaW5kaWNhdGluZyB0aGF0IGluZGl2aWR1YWwgaWRlbnRpdHkgZXhwbGFpbmVkIGEgbWVhbmluZ2Z1bCBwcm9wb3J0aW9uIG9mIHRoZSBvYnNlcnZlZCB2YXJpYXRpb24uDQoNCmBgYHtyfQ0KcmFuZG9tX2VmZmVjdCA8LSBzdW1tYXJ5KG1vMl9tb2RfZ2FtbWEpJHJhbmRvbSRpZA0KcmFuZG9tX2VmZmVjdCAlPiUgDQogIGd0KCkNCmBgYA0KDQoNCg0KIyMgTUVOVElPTiBSIHZhdWxlcyB3aXRoIHRleHQgZnJvbSBNUw0KDQojIyBTTVINCg0KIyMjIEZvcm1hdGluZyBhbmQgc2NhbGluZyBkYXRhDQoNCkhlcmUgd2UgYXJlIGZpbHRlcmluZyB0aGUgZGF0YSBmcmFtZSB0byBoYXZlIG9ubHkgbWVhc3VyZSBwZXIgZmlzaCBmb3IgdGhlIFNNUiBlc3RpbWF0ZQ0KDQpgYGB7cn0NCnNjYWxlX2xpc3QgPC0gYygidGVtcF9tZWFuIiwgImxvZ19tYXNzIiwgImN5Y2xlcyIpDQoNCnNtciA8LSBzbG9wZV90aWR5X3NtciAlPiUNCiAgZHBseXI6Omdyb3VwX2J5KGlkKSAlPiUgDQogIGRwbHlyOjpyZWZyYW1lKHRlbXBfbWVhbiA9IG1lYW4odGVtcCksDQogICAgICAgICAgICAgICAgIGxvZ19tYXNzID0gbG9nX21hc3NbMV0sDQogICAgICAgICAgICAgICAgIG1hc3MgPSBtYXNzWzFdLA0KICAgICAgICAgICAgICAgICBTTVIgPSBTTVJbMV0sDQogICAgICAgICAgICAgICAgIHNhbGluaXR5X2dyb3VwID0gc2FsaW5pdHlfZ3JvdXBbMV0sDQogICAgICAgICAgICAgICAgIGN5Y2xlcyA9IGxlbmd0aChvcmRlcikpICU+JSANCiAgZHBseXI6Om11dGF0ZShhY3Jvc3MoYWxsX29mKHNjYWxlX2xpc3QpLCB+IHNjYWxlKC54LCBjZW50ZXIgPSBUUlVFLCBzY2FsZSA9IEZBTFNFKSwNCiAgICAgICAgICAgICAgICAgICAgICAgLm5hbWVzID0gInsuY29sfV9jIikpDQpgYGANCg0KU3VtbWFyeSBvZiBwcmVkaWN0b3JzIHVzZWQgaW4gdGhlIG1vZGVsIGJlbG93DQoNCmBgYHtyfQ0Kc21yICU+JQ0KICBkcGx5cjo6cmVmcmFtZSh0ZW1wX3JhbmdlID0gcGFzdGUwKHJvdW5kKG1pbih0ZW1wX21lYW4sIG5hLnJtID0gVFJVRSksMiksICLigJMiLCByb3VuZChtYXgodGVtcF9tZWFuLCBuYS5ybSA9IFRSVUUpLDIpKSwNCiAgICAgICAgICAgIG1hc3NfcmFuZ2UgPSBwYXN0ZTAocm91bmQobWluKG1hc3MsIG5hLnJtID0gVFJVRSksMiksICLigJMiLCByb3VuZChtYXgobWFzcywgbmEucm0gPSBUUlVFKSwyKSksDQogICAgICAgICAgY3ljbGVfcmFuZ2UgPSBwYXN0ZTAocm91bmQobWluKGN5Y2xlcywgbmEucm0gPSBUUlVFKSwyKSwgIuKAkyIsIHJvdW5kKG1heChjeWNsZXMsIG5hLnJtID0gVFJVRSksMikpLA0KICAgICAgICAgIG51bWJlcl9maXNoID0gbGVuZ3RoKHVuaXF1ZShpZCkpICANCiAgICAgICAgICApICU+JSANCiAgZ3QoKQ0KYGBgDQoNCiMjIyBNb2RlbCBzdHJ1Y3R1cmUNCg0KSGVyZSB3ZSB3aWxsIHVzZSBhIEJheWVzaWFuIEdlbmVyYWxpc2VkIExpbmVhciBNaXhlZCBNb2RlbCAoR0xNTSkgd2l0aCBhIEdhbW1hIGRpc3RyaWJ1dGlvbiBhbmQgYSBsb2cgbGluayBgR2FtbWEobGluayA9ICJsb2ciKWAsIHdoZXJlIHRoZSBzaGFwZSBwYXJhbWV0ZXIgKM6xKSBpcyBhbHNvIG1vZGVsbGVkIGFzIGEgZnVuY3Rpb24gb2YgdGhlIHNhbGluaXR5IGdyb3VwLCBgc2hhcGUgfiBzYWxpbml0eV9ncm91cGAuIFRoaXMgbW9kZWxzIE1PMiBieSBzYWxpbml0eSBkdXJpbmcgdGhlIFNNUiBwaGFzZSB0byBzZWUgaWYgdGhlIGZpc2ggaGVsZCBhdCBkaWZmZXJlbnQgc2FsaW5pdGllcyBoYXZlIGRpZmZlcmVudCBTTVJzLiBXZSBoYXZlIGFsc28gYWRkZWQgYSBmZXcgc2NhbGVkIHByZWRpY3RvcnMsIHRoYXQgbWF5IGhlbHAgZGVzY3JpYmUgdmFyaWF0aW9uIGluIHRoZSBkYXRhLCBzdWNoIGFzIGZpc2ggbWFzcyAoZzsgMC4yMS0tMS42KSBtZWFuIHRlbXBlcmF0dXJlICjCsEM7IDEzLjg0MS0tMTQuMjc3KSwgYW5kIHRoZSBudW1iZXIgb2YgY3ljbGVzIG92ZXIgd2hpY2ggU01SIHdhcyBlc3RpbWF0ZWQgKDEtLTIzKS4gV2UgYWxsb3dlZCB0aGUgdGhlIHNoYXBlIHBhcmFtZXRlciAozrEpIHRvIHZhcnkgYXMgYSBmdW5jdGlvbiBvZiBzYWxpbml0eV9ncm91cCB0byBpbXByb3ZlIGZpdC4NCg0KYGBge3J9DQpzbXJfZ2FtbWFfYmYgPC0gYmYoU01SIH4gdGVtcF9tZWFuX2MgKyANCiAgICAgICAgICAgICAgICAgIGN5Y2xlc19jICArDQogICAgICAgICAgICAgICAgICBsb2dfbWFzc19jICsgDQogICAgICAgICAgICAgICAgICBzYWxpbml0eV9ncm91cCwNCiAgICAgICAgICAgICAgICAgIHNoYXBlIH4gc2FsaW5pdHlfZ3JvdXAsDQogICAgICAgICAgICAgICAgICBmYW1pbHkgPSBHYW1tYShsaW5rID0gImxvZyIpKQ0KYGBgDQoNCiMjIyBQcmlvciBzZWxlY3Rpb24NCg0KVGhlc2UgYXJlIHRoZSBkZWZhdWx0IHByaW9ycyBmb3IgdGhlIG1vZGVsLiBXZSB3aWxsIHVzZSB0aGVzZS4NCg0KYGBge3J9DQpwcmlvcnNfZGVmYXVsdCA8LSBnZXRfcHJpb3Ioc21yX2dhbW1hX2JmLCBkYXRhID0gc21yLCBmYW1pbHkgPSBHYW1tYShsaW5rID0gImxvZyIpKQ0KcHJpb3JzX2RlZmF1bHQgJT4lIA0KICBndCgpDQpgYGANCg0KIyMjIFJ1biBtb2RlbA0KDQpIZXJlIHdlIHJ1biB0aGUgbW9kZWwsIEkgaGF2ZSBoYXNoZWQgdGhpcyBvdXQgYmVjYXVzZSBJIGhhdmUgc2F2ZWQgdGhlIG1vZGVsIGZvciBxdWljayByZWxvYWRpbmcuDQoNCuKPre+4jyAqKlNraXAgdGhpcyBzdGVwKiogaWYgeW91IGhhdmUgZG93bmxvYWRlZCB0aGUgc2F2ZWQgbW9kZWwgJ3Ntcl9tb2RfZ2FtbWEucmRzJw0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCiMgc21yX21vZF9nYW1tYV9jIDwtIGJybShzbXJfZ2FtbWFfYmYsDQojICAgICAgICAgICAgICAgIGRhdGEgPSBzbXIsDQojICAgICAgICAgICAgICAgIGNvcmVzID0gNCwNCiMgICAgICAgICAgICAgICAgY2hhaW5zID0gNCwNCiMgICAgICAgICAgICAgICAgcHJpb3IgPSBwcmlvcnNfZGVmYXVsdCwNCiMgICAgICAgICAgICAgICAgd2FybXVwID0gMTAwMCwNCiMgICAgICAgICAgICAgICAgc2VlZCA9IDE0MzAxOSwNCiMgICAgICAgICAgICAgICAgdGhpbiA9IDIsDQojICAgICAgICAgICAgICAgIGl0ZXIgPSA4MDAwLA0KIyAgICAgICAgICAgICAgICBzYXZlX3BhcnMgPSBzYXZlX3BhcnMoYWxsPVRSVUUpLA0KIyAgICAgICAgICAgICAgICBzYW1wbGVfcHJpb3IgPSBUUlVFLA0KIyAgICAgICAgICAgICAgICBmaWxlID0gcGFzdGUwKG91dHB1dF9tb2RzX3dkLCAnLi9zbXJfbW9kX2dhbW1hJykpDQojIHByaW50KCJNb2RlbCBjb21wbGV0ZSIpDQpgYGANCg0KSGVyZSB3ZSByZWxvYWQgdGhlIG1vZGVsDQoNCmBgYHtyfQ0Kc21yX21vZF9nYW1tYSA8LSAgcmVhZFJEUyhmaWxlID0gcGFzdGUwKG91dHB1dF9tb2RzX3dkLCAnLi9zbXJfbW9kX2dhbW1hLnJkcycpKQ0KYGBgDQoNCiMjIyBNb2RlbCBkaWFnbm9zdGljcw0KDQpDaGVja2luZyBtb2RlbCBjb252ZXJnZW5jZQ0KDQpgYGB7cn0NCmNvbG9yX3NjaGVtZV9zZXQoInJlZCIpDQpwbG90KHNtcl9tb2RfZ2FtbWEsIGFzayA9IEYpDQpgYGANCg0KVXNpbmcgbGVhdmUgb25lIG91dCAobG9vKSBtZWFzdXJlIG9mIGZpdCwgdGhlIG1vZGVsIGFwcGVhcnMgdG8gcHJlZm9ybSB3ZWxsLCB0d28gUGFyZXRvIGsgZXN0aW1hdGVzIGZhbGxzIG91dHNpZGUgdGhlIGdvb2QgcmFuZ2UgKDAuNywgMV0NCg0KYGBge3J9DQpsb28oc21yX21vZF9nYW1tYSkNCmBgYA0KDQpNb2RlbCBwcmVkaWN0aW9ucyBnZW5lcmFsbHkgYWxpZ24gd2l0aCB0aGUgb2JzZXJ2ZWQgZGF0YSwgYnV0IHRoZXJlIGlzIGEgbG90IG9mIHVuY2VydGFpbnR5IGFyb3VuZCB0aGlzIGVzdGltYXRlLg0KDQpgYGB7cn0NCmNvbG9yX3NjaGVtZV9zZXQoInJlZCIpDQpwIDwtIHBwX2NoZWNrKHNtcl9tb2RfZ2FtbWEsIHR5cGUgPSAiZGVuc19vdmVybGF5IikNCnANCmBgYA0KDQojIyMg8J+TiCBSZXN1bHRzDQoNCldlIGRpZCBub3Qgc2VlIGEgbWVhbmluZ2Z1bCBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHJvdXRpbmUgbWV0YWJvbGljIHJhdGUgZm9yIGZpc2ggZnJvbSB0aGUgdHdvIHNhbGluaXR5IHRyZWF0bWVudHMuDQoNCiMjIyMgVGFibGUgUzINCg0KKipUYWJsZSBTMjoqKiBGaXhlZCBlZmZlY3QgRXN0aW1hdGVzICjOsikgYW5kIDk1JSBDcmVkaWJsZSBJbnRlcnZhbHMgKDk1JSBDSSkgZnJvbSBhIEJheWVzaWFuIEdlbmVyYWxpc2VkIExpbmVhciBNaXhlZCBNb2RlbCAoR0xNTSkgd2l0aCBhIEdhbW1hIGRpc3RyaWJ1dGlvbiBhbmQgYSBsb2cgbGluaw0KDQpgYGB7cn0NCm1vZGVsX2VzdCA8LSBmaXhlZihzbXJfbW9kX2dhbW1hLCBwcm9icyA9IGMoMC4wMjUsIDAuOTc1KSkgJT4lIA0KICBhcy5kYXRhLmZyYW1lKCkgJT4lIA0KICB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbih2YXIgPSAiUHJlZGljdG9yIikgJT4lIA0KICBkcGx5cjo6bXV0YXRlKCfOsicgPSByb3VuZChFc3RpbWF0ZSwgMyksDQogICAgICAgICAgICAgICAgUTIuNSA9IHJvdW5kKFEyLjUsIDMpLA0KICAgICAgICAgICAgICAgIFE5Ny41ID0gcm91bmQoUTk3LjUsIDMpLA0KICAgICAgICAgICAgICAgICc5NSUgQ0knID0gcGFzdGUwKCJbIiwgUTIuNSwgIiwgIiwgUTk3LjUsICJdIikpDQoNCm1vZGVsX2VzdCAlPiUgDQogIGRwbHlyOjpzZWxlY3QoUHJlZGljdG9yLCAnzrInLCAnOTUlIENJJykgJT4lIA0KICBndCgpDQpgYGANCg0KTG9va2luZyBhdCB0aGUgbWFyZ2luYWwgbWVhbiBkaWZmZXJlbmNlIGJldHdlZW4gc2FsaW5pdHkgZ3JvdXBzDQoNCmBgYHtyfQ0KZW1fcmVzdWx0cyA8LSBlbW1lYW5zKHNtcl9tb2RfZ2FtbWEsIH4gc2FsaW5pdHlfZ3JvdXApIA0KDQplbV9yZXN1bHRzX2RmIDwtICBlbV9yZXN1bHRzICU+JSANCiAgYXMuZGF0YS5mcmFtZSgpICU+JQ0KICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IHJvdW5kKGV4cCguKSwzKSkpDQoNCg0KZW1fcmVzdWx0c19kZiAlPiUgDQogIGd0KCkNCmBgYA0KDQpgYGB7cn0NCmNvbnRyYXN0X3Jlc3VsdHNfZGYgPC0gIGNvbnRyYXN0X3Jlc3VsdHMgJT4lIA0KICBhcy5kYXRhLmZyYW1lKCkgJT4lDQogIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIH4gZXhwKC4pKSkNCg0KY29udHJhc3QoZW1fcmVzdWx0cywgbWV0aG9kID0gInBhaXJ3aXNlIikgJT4lIA0KICBhcy5kYXRhLmZyYW1lKCkgJT4lDQogIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIH4gcm91bmQoZXhwKC4pLDIpKSkgJT4lIA0KICBndCgpDQpgYGANCg0KSGVyZSB3ZSB3ZSBjYWxjdWxhdGUgdGhlIG1vZGVsLWVzdGltYXRlZCBtYXJnaW5hbCBtZWFucyBmb3IgU01SIGZvciBhIHVuaXQgaW5jcmVhc2UgaW4gbWFzcyBhbmQgdHJhbnNmb3JtIHRoaXMgb250byBhIGZvbGQtY2hhbmdlIHNjYWxlLiBXaGVyZSBsb2cobWFzcykgaGFzIGJlIGNlbnRlcmVkLCBhIHZhdWxlIG9mIDAgcmVwcmVzZW50cyB0aGUgbWVhbiBtYXNzIG9mIGZpc2gsIGFuZCAxIGNvcnJlc3BvbmRzIHRvIGEgZmlzaCB3aXRoIGxvZyhtYXNzKSA9IDEgdW5pdCBhYm92ZSB0aGUgbWVhbiAoaS5lLiAyLjcgdGltZXMgbGFyZ2UpLg0KDQpgYGB7cn0NCmVtX21hc3MgPC0gZW1tZWFucyhzbXJfbW9kX2dhbW1hLCB+IGxvZ19tYXNzX2MsIGF0ID0gbGlzdChsb2dfbWFzc19jID0gYygwLCAxKSkpDQoNCiMgR2V0IHRoZSBjb250cmFzdCAoZGlmZmVyZW5jZSBpbiBsb2cgTU/igoIpLCB0aGVuIGJhY2stdHJhbnNmb3JtDQpjb250cmFzdChlbV9tYXNzLCBtZXRob2QgPSAicmV2cGFpcndpc2UiKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSgpICU+JQ0KICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCBleHApKSAlPiUNCiAgbXV0YXRlKGFjcm9zcyh3aGVyZShpcy5udW1lcmljKSwgfiByb3VuZCguLCAyKSkpICU+JQ0KICBndCgpDQpgYGANCg0KUHVsbGluZyB0aGUgZW1tZWFucyBkcmF3cyBmb3Igb3VyIHBsb3QNCg0KYGBge3J9DQplbW1lYW5zX2RyYXdfc21yIDwtIHNtcl9tb2RfZ2FtbWEgJT4lDQogIGVtbWVhbnMofiBzYWxpbml0eV9ncm91cCkgJT4lDQogIGdhdGhlcl9lbW1lYW5zX2RyYXdzKCkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKC52YWx1ZSA9ICBleHAoLnZhbHVlKSwNCiAgICAgICAgICAgICAgICBzYWxpbml0eV9ncm91cCA9IGFzLmNoYXJhY3RlcihzYWxpbml0eV9ncm91cCkpDQoNCmVtbWVhbnNfY29udHJhc3RfZHJhd3Nfc21yIDwtICBzbXJfbW9kX2dhbW1hICU+JQ0KICBlbW1lYW5zKH4gc2FsaW5pdHlfZ3JvdXApICU+JQ0KICBjb250cmFzdChtZXRob2QgPSAicGFpcndpc2UiKSAlPiUNCiAgZ2F0aGVyX2VtbWVhbnNfZHJhd3MoKSAlPiUgDQogIGRwbHlyOjptdXRhdGUoLnZhbHVlID0gIGV4cCgudmFsdWUpKQ0KYGBgDQoNCiMjIyMgRmlndXJlIDFiDQoNCioqTk9URTogVGhpcyBwbG90IGlzIGluIHRoZSBtYWluIHRleHQgb2YgdGhlIG1hbnVzY3JpcHQgd2hpY2ggaXMgd2h5IGl0IGlzIEZpZ3VyZSAxYiAobm90IEZpZ3VyZSBTaSkqKg0KDQpgYGB7cn0NCm1lYW5fc21yX3NhbGluaXR5IDwtIHNtciAlPiUNCiAgZHBseXI6Omdyb3VwX2J5KHNhbGluaXR5X2dyb3VwKSAlPiUNCiAgZHBseXI6OnJlZnJhbWUobWVhbl9TTVIgPSBtZWFuKFNNUiwgbmEucm0gPSBUUlVFKSkNCg0KDQpmaWdfMWIgPC0gZ2dwbG90KCkgKw0KICBnZW9tX3Zpb2xpbihkYXRhID0gc21yLA0KICAgICAgICAgICAgICBhZXMoeCA9IHNhbGluaXR5X2dyb3VwLCB5ID0gU01SLCBmaWxsID0gc2FsaW5pdHlfZ3JvdXApLA0KICAgICAgICAgICAgICBjb2xvciA9IE5BLCBhbHBoYSA9IDAuMikgKw0KICBnZW9tX2ppdHRlcihkYXRhID0gc21yLA0KICAgICAgICAgICAgICBhZXMoeCA9IHNhbGluaXR5X2dyb3VwLCB5ID0gU01SLCBmaWxsID0gc2FsaW5pdHlfZ3JvdXApLA0KICAgICAgICAgICAgICBzaGFwZSA9IDIxLCB3aWR0aCA9IDAuMywgc2l6ZSA9IDEsIGNvbG9yID0gImJsYWNrIiwgYWxwaGEgPSAwLjEpICsNCiAgZ2VvbV9wb2ludChkYXRhID0gbWVhbl9zbXJfc2FsaW5pdHksDQogICAgICAgICAgICAgYWVzKHggPSBzYWxpbml0eV9ncm91cCwgeSA9IG1lYW5fU01SLCBmaWxsID0gc2FsaW5pdHlfZ3JvdXApLA0KICAgICAgICAgICAgIHNpemUgPSA0LCBhbHBoYSA9IDEsIHN0cm9rZSA9IDIsIGNvbG9yID0gImJsYWNrIiwgc2hhcGUgPSAyMSwNCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX251ZGdlKHggPSAwLjA1KSkgKw0KICBzdGF0X3BvaW50aW50ZXJ2YWwoZGF0YSA9IGVtbWVhbnNfZHJhd19zbXIsDQogICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IHNhbGluaXR5X2dyb3VwLCB5ID0gLnZhbHVlKSwNCiAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9ICJncmV5IiwgcG9pbnRfaW50ZXJ2YWwgPSAibWVhbl9xaSIsIC53aWR0aCA9IDAuOTUsIHNoYXBlID0gMjEsICBzdHJva2UgPSAyLCBwb2ludF9zaXplID0gNCwgYWxwaGEgPSAxLA0KICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9udWRnZSh4ID0gLTAuMDUpKSArDQogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAuMDAsIDAuMzUpKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiM0QjUzMjAiLCAiIzAwMDA4MCIpKSArICAjIEN1c3RvbSBmaWxsIGNvbG91cnMNCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCIjNEI1MzIwIiwgIiMwMDAwODAiKSkgKw0KICB0aGVtZSgNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiYmxhY2siLCBmaWxsID0gTkEsIGxpbmV3aWR0aCA9IDEpLA0KICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIsIGNvbG91ciA9IE5BKSwNCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIsIGNvbG91ciA9IE5BKQ0KICApICsNCiAgbGFicygNCiAgICBzdWJ0aXRsZSA9ICIiLA0KICAgIHggPSAiU2FsaW5pdHkgZ3JvdXAgKHBwdCkiLA0KICAgIHkgPSAiU3RhbmRhcmQgbWV0YWJvbGljIHJhdGUgKFNNUjsgbWcgTzIgZy9oKSINCiAgKQ0KDQpmaWdfMWINCmBgYA0KDQoNCioqRmlndXJlIDFiOioqIFRoZSBzdGFuZGFyZCBtZXRhYm9saWMgcmF0ZSBlc3RpbWF0ZSAobWdeLTFeIE88c3ViPjI8L3N1Yj4gaF4tMV4pIHBsb3R0ZWQgYnkgc2FsaW5pdHkgdHJlYXRtZW50LiBUaGUgc21hbGwgdHJhbnNwYXJlbnQgcG9pbnRzIGFyZSB0aGUgb2JzZXJ2ZWQgdmFsdWVzLCB0aGUgc2hhZGVkIGFyZWEgYmVoaW5kIHRoZSBwb2ludHMgaXMgdGhlIGEga2VybmVsIGRlbnNpdHkgb2YgdGhlIG9ic2VydmVkIGRhdGEsIHRoZSBsYXJnZSBjb2xvdXJlZCBwb2ludCAodG8gdGhlIHJpZ2h0KSBpcyB0aGUgb2JzZXJ2ZWQgbWVhbiwgdGhlIGxhcmdlIGdyZXkgcG9pbnQgd2l0aCBlcnJvciBiYXJzICh0byB0aGUgbGVmdCkgaXMgdGhlIG1vZGVsIGVzdGltYXRlZCBtYXJnaW5hbCBtZWFuIChlZW1lYW4pIDk1JSBDcmVkaWJsZSBJbnRlcnZhbHMgKDk1JSBDSSkuDQoNCmBgYHtyfQ0KIyBnZ3NhdmUoZmlsZW5hbWUgPSBwYXN0ZTAob3V0cHV0X2ZpZ193ZCwgIi4vbXNfZmlndXJlcy4vZmlndXJlLTFiLnBkZiIpLA0KIyAgICAgICAgcGxvdCA9IGZpZ18xYiwNCiMgICAgICAgIHdpZHRoID0gMjEwLzIsDQojICAgICAgICBoZWlnaHQgPSAyOTcvMiwgICMgU3BlY2lmeSB0aGUgaGVpZ2h0IG9mIHRoZSBwbG90DQojICAgICAgICB1bml0cyA9ICJtbSIpDQpgYGANCg0KIyMgSW5jcmVtZW50YWwgcmVncmVzc2lvbiBhbmFseXNlcw0KDQpIZXJlIHdlIGFyZSBmb2xsb3dpbmcgdGhlIG1ldGhvZHMgVXJiaW5hIGV0IGFsLiAoMjAxMileWzFdXiB3aXRoIGFuIGluY3JlbWVudGFsIHJlZ3Jlc3Npb24gYW5hbHlzZXMsIGluIG9yZGVyIHRvIGRldGVybWluZSB0aGUgYmVzdCBmaXQgZm9yIHRoZSBNTzxzdWI+Mjwvc3ViPiB2cyBPPHN1Yj4yPC9zdWI+IGRhdGENCg0KVGhpcyBhbmFseXNpcyBhcHByb2FjaCBldmFsdWF0ZXMgdGhlIHJlbGF0aXZlICdmaXQnIG9mIGVhY2ggcG9seW5vbWlhbCBvcmRlciBlcXVhdGlvbiBzdGFydGluZyBhdCB6ZXJvIGFuZCBpbmNyZWFzaW5nIHRvIHRoZSB0aGlyZCBvcmRlciwgcGVybWl0dGluZyBhIG1hdGhlbWF0aWNhbCBhc3Nlc3NtZW50IG9mIHdoZXRoZXIgZmlzaCB3ZXJlIG94eWNvbmZvcm1pbmcgb3Igb3h5cmVndWxhdG9yaW5nLiBJZiB0aGUgZGF0YSBpcyBiZXN0IGZpdHRlZC9wcmVkaWN0ZWQgYnkgYSBzaW5nbGUgbGluZWFyIHJlbGF0aW9uc2hpcCAoMV5zdF4tb3JkZXIgcG9seW5vbWlhbCkgd2l0aCBhIHBvc2l0aXZlIHNsb3BlLCB0aGlzIHdvdWxkIHN1Z2dlc3RzIHRoZSBmaXNoIHdlcmUgb3h5Y29uZm9ybWluZy4gQWx0ZXJuYXRlbHksIGlmIHRoZSByZWxhdGlvbnNoaXAgaXMgYmVzdCBtb2RlbGxlZCBieSBhIGZsYXQgcmVncmVzc2lvbiAoMF50aF4tb3JkZXIgcG9seW5vbWlhbCksIG9yIGEgaGlnaGVyIG9yZGVyIHBvbHlub21pYWwgKDJebmReIG9yIDNecmReLW9yZGVyIHBvbHlub21pYWwpIHRoZSBmaXNoIGlzIGxpa2VseSBveHlyZWd1bGF0b3JpbmcuDQoNCiMjIyBCdWlsZGluZyBCYXllc2lhbiByZWdyZXNzaW9ucw0KDQpIZXJlIHdlIGFyZSB1c2luZyBhIEJheWVzaWFuIGFwcHJvYWNoIHRvIG1vZGVsIGZpdHRpbmcgd2l0aCBicm0uIFRoZXNlIG1vZGVscyB0YWtlIGEgbG9uZyB0aW1lIHRvIHJ1biwgc28gSSBoYXZlIHNhdmVkIHRoZW0gYW5kIHJlLWxvYWRlZCB0aGVtIHRvIHNhdmUgdGltZS4gSSBoYXZlIGFsc28gc2F2ZWQgdGhlIHN1bW1hcnkgZGF0YSBwcm9kdWNlZCBmcm9tIHRoZSBtb2RlbHMsIHRvIHNhdmUgdGltZSwgeW91IGNhbiBzaW1wbHkgc2tpcCB0aGUgaGFzaGVkIGNvZGUgYW5kIGlucHV0IHRoZSByZXN1bHRpbmcgc3VtbWFyeSBkYXRhLg0KDQpXZSB3aWxsIHJ1biBvdXIgY3VzdG9tIGZ1bmN0aW9uLCBgYmF5ZXNfaW5jcmVtZW50YWxfcmVncmVzc2lvbl9ieV9pZGAuDQoNCkxldCdzIG1ha2UgZGVmaW5lIHRoZSBvdXRwdXQgZGlyZWN0b3J5DQoNCmBgYHtyfQ0Kb3V0cHV0X21vZHNfYmF5ZXNfd2QgPC0gcGFzdGUwKHdkLCAiLi9vdXRwdXQtbW9kLi9iYXllcy1yZWdzIikNCmBgYA0KDQrij63vuI8gKipTa2lwIHRoaXMgc3RlcCoqIGlmIHlvdSBoYXZlIGFscmVhZHkgcnVuIHRoaXMgb25jZSwgb3IgaGF2ZSBkb3dubG9hZGVkIHRoZSBzYXZlZCBtb2RlbHMgb3Igc2F2ZWQgZGF0YSBmaWxlcyBmcm9tIEdpdEh1YiAodGhhdCdzIHdoeSBpdHMgaGFzaGVkIG91dCkuIOKMmypUaGlzIGNvZGUgdGFrZXMgYSB3aGlsZSB0byBydW4gKuKMmw0KDQpEdXJpbmcgdGhpcyBwYXJ0IG9mIHRoZSBzY3JpcHQgSSByZWNlaXZlZCBhbiBlcnJvciwgJ0NhdXNlZCBieSBlcnJvciBpbiBgc29ja2V0Q29ubmVjdGlvbigpYDonLiBJIHRoaW5rIHRoZSBzeXN0ZW0gbWF5IGJlIGhpdHRpbmcgYSBsaW1pdCBvbiB0aGUgbnVtYmVyIG9mIHNpbXVsdGFuZW91cyBzb2NrZXQgY29ubmVjdGlvbnMuIElmIHlvdSB0aGlzIHBhcnQgb2YgdGhlIGNvZGUgYW5kIGFsc28gZ2V0IHRoaXMgaXNzdWUsIHRyeSByZWR1Y2luZyB0aGUgbnVtYmVyIG9mIHBhcmFsbGVsIHdvcmtlcnM6IHBsYW4obXVsdGlzZXNzaW9uLCB3b3JrZXJzID0gMiksIG9yIHJ1biBhZ2FpbiBhZnRlciB0aGUgZXJyb3IuDQoNCmBgYHtyLCByZXN1bHRzPSdoaWRlJ30NCiMgaWRzIDwtIHNsb3BlX3RpZHkgJT4lDQojICAgZHBseXI6OmRpc3RpbmN0KGlkKSAlPiUNCiMgICBwdWxsKGlkKQ0KIyANCiMgcGxhbihtdWx0aXNlc3Npb24pDQojIA0KIyBmdXR1cmVfbWFwKA0KIyAgIGlkcywNCiMgICBiYXllc19pbmNyZW1lbnRhbF9yZWdyZXNzaW9uX2J5X2lkLA0KIyAgIGlkX25hbWUgPSAiaWQiLA0KIyAgIGRhdGEgPSBzbG9wZV90aWR5LA0KIyAgIHJlc3BvbnNlID0gIk1PMl9nIiwNCiMgICBwcmVkaWN0b3IgPSAiRE8iLA0KIyAgIHNlZWRfbnVtYmVyID0gMTQzMDE5LA0KIyAgIHNhdmVfbW9kZWxzID0gVFJVRSwNCiMgICBtb2Rfb3V0cHV0X3dkID0gb3V0cHV0X21vZHNfYmF5ZXNfd2QNCiMgKQ0KIyANCiMgcGxhbihzZXF1ZW50aWFsKQ0KYGBgDQoNCkxvYWQgYWxsIG1vZGVscyBhbmQgc3RvcmUgaW4gYSBsaXN0LCB3aWxsIHVzZSBhIGxvdCBvZiBtZW1vcnkuIFlvdSBjYW4gYWxzbyBza2lwIHRoaXMgc3RlcCBhbmQgbG9hZCB0aGUgcmVzdWx0aW5nIGRhdGEgZnJhbWVzIGJlbG93LiBJIGFtIHVzaW5nIHRoZSBjdXN0b20gZnVuY3Rpb24gYGxvYWRfcmRzYCwgc28gd2UgY2FuIGNvbXBhcmUgdGhlbSBhbmQgZ2VuZXJhdGUgcHJlZGljdGlvbnMuDQoNCuKPre+4jyAqKlNraXAgdGhpcyBzdGVwKiogaWYgeW91IGhhdmUgZG93bmxvYWRlZCB0aGUgc2F2ZWQgZGF0YSBwdWxsZWQgZnJvbSB0aGVzZSBtb2RlbHMgaGF2ZSBhbHNvIGhhc2VkIHRoaXMgb3V0LCBiYXllc19yZWdfbW9kc19maXQuY3N2JyBhbmQgJ2JheWVzX3JlZ19tb2RzX3ByZWRpY3Rpb25zLmNzdicuIFRoZXNlIGFyZSBpbiB0aGUgbW9kLWRhdGEgZGlyZWN0b3J5Lg0KDQpgYGB7cn0NCiMgYmF5ZXNfcmVnX21vZHMgPC0gbG9hZF9yZHMobW9kZWxfZHcgPSBvdXRwdXRfbW9kc19iYXllc193ZCkNCmBgYA0KDQojIyMgTW9kZWwgZml0cw0KDQrij63vuI8gKipTa2lwIHRoaXMgc3RlcCoqIGlmIHlvdSBoYXZlIGRvd25sb2FkZWQgKirwn5K/IGJheWVzX3JlZ19tb2RzX2ZpdC5jc3YqKi4NCg0KSXQgZ2V0cyBtb2RlbCBmaXQgcGFyYW1ldGVycyBsb28gYW5kIHIyIHVzaW5nIHRoZSBjdXN0b20gZnVuY3Rpb24sIGBpbmNyZW1lbnRhbF9yZWdyZXNzaW9uX2JheWVzX2ZpdHNgLiAq4oybIFRoaXMgY29kZSB0YWtlcyBhIHdoaWxlIHRvIHJ1biDijJsqDQoNCmBgYHtyfQ0KIyBiYXllc19yZWdfbW9kc19maXQgPC0gaW5jcmVtZW50YWxfcmVncmVzc2lvbl9iYXllc19maXRzKG1vZGVscyA9IGJheWVzX3JlZ19tb2RzKQ0KIyB3cml0ZS5jc3YoYmF5ZXNfcmVnX21vZHNfZml0LCBwYXN0ZTAobW9kX2RhdGFfd2QsICIuL2JheWVzX3JlZ19tb2RzX2ZpdC5jc3YiKSwgcm93Lm5hbWVzID0gRkFMU0UpDQpgYGANCg0KUmVhZGluZyBpbiB0aGlzIG1vZGVsIGZpdCBkYXRhIGZyYW1lLCBpbiB0aGUgY2FzZSB5b3UgZGlkIG5vdCBsb2FkIGluIGFsbCB0aGUgbW9kZWxzLg0KDQpgYGB7cn0NCmJheWVzX3JlZ19tb2RzX2ZpdCA8LSByZWFkLmNzdihwYXN0ZTAobW9kX2RhdGFfd2QsICIuL2JheWVzX3JlZ19tb2RzX2ZpdC5jc3YiKSkNCmBgYA0KDQoqKlNlbGVjdGluZyB0aGUgYmVzdCBmaXR0aW5nIG1vZGVsKioNCg0KZWxwZF9sb28sIG9yIHRoZSBleHBlY3RlZCBsb2cgcG9pbnR3aXNlIHByZWRpY3RpdmUgZGVuc2l0eSBmb3IgbGVhdmUtb25lLW91dCBjcm9zcy12YWxpZGF0aW9uLCBpcyBhIG1ldHJpYyB1c2VkIGluIEJheWVzaWFuIG1vZGVsIGV2YWx1YXRpb24gdG8gYXNzZXNzIHRoZSBwcmVkaWN0aXZlIGFjY3VyYWN5IG9mIGEgbW9kZWwuIFRoZSBlbHBkX2xvbyBpcyBhbiBhcHByb3hpbWF0aW9uIG9mIGhvdyB3ZWxsIHRoZSBtb2RlbCBpcyBleHBlY3RlZCB0byBwcmVkaWN0IG5ldyBkYXRhLCBiYXNlZCBvbiBsZWF2ZS1vbmUtb3V0IGNyb3NzLXZhbGlkYXRpb24uIEhpZ2hlciBlbHBkX2xvbyB2YWx1ZXMgaW5kaWNhdGUgYmV0dGVyIHByZWRpY3RpdmUgcGVyZm9ybWFuY2UuDQoNCmBgYHtyfQ0KYmVzdF9maXRfYmF5ZXNfcmVnIDwtIGJheWVzX3JlZ19tb2RzX2ZpdCAlPiUNCiAgZHBseXI6Omdyb3VwX2J5KGlkKSAlPiUNCiAgZHBseXI6Om11dGF0ZShlbHBkX2xvb19yYW5rID0gcmFuaygtZWxwZF9sb28pKSAlPiUNCiAgZHBseXI6OnNlbGVjdChpZCwgbW9kZWxfdHlwZSwgZWxwZF9sb28sIHIyLCBlbHBkX2xvb19yYW5rLCByMl9xMi41LCByMl9xOTcuNSwgZXN0aW1hdGVfRE8sIGNvbmYubG93X0RPLCBjb25mLmhpZ2hfRE8pICU+JQ0KICB1bmdyb3VwKCkNCmBgYA0KDQojIyMgTW9kZWwgcHJlZGljdGlvbnMNCg0K4o+t77iPICoqU2tpcCB0aGlzIHN0ZXAqKiBpZiB5b3UgaGF2ZSBkb3dubG9hZGVkICoq8J+SvyBiYXllc19yZWdfbW9kc19wcmVkaWN0aW9ucy5jc3YqKi4NCg0KSXQgcHVsbHMgb3VyIG1vZGVsIHByZWRpY3Rpb25zIHVzaW5nIGEgY3VzdG9tIGZ1bmN0aW9uIGBiYXllc19tb2RfcHJlZGljdGlvbnNgLg0KDQpgYGB7cn0NCiMgYmF5ZXNfcmVnX21vZHNfcHJlZGljdGlvbnMgPC0gYmF5ZXNfbW9kX3ByZWRpY3Rpb25zKG1vZGVscyA9IGJheWVzX3JlZ19tb2RzLCBvcmlnaW5hbF9kYXRhID0gc2xvcGVfdGlkeSkNCiMgd3JpdGUuY3N2KGJheWVzX3JlZ19tb2RzX3ByZWRpY3Rpb25zLCBwYXN0ZTAobW9kX2RhdGFfd2QsICIuL2JheWVzX3JlZ19tb2RzX3ByZWRpY3Rpb25zLmNzdiIpLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KDQpSZWFkaW5nIGluIHRoZSBwcmVkaWN0ZWQgZGF0YQ0KDQpgYGB7cn0NCmJheWVzX3JlZ19tb2RzX3ByZWRpY3Rpb25zIDwtIHJlYWQuY3N2KHBhc3RlMChtb2RfZGF0YV93ZCwgIi4vYmF5ZXNfcmVnX21vZHNfcHJlZGljdGlvbnMuY3N2IikpDQpgYGANCg0KV2UgYXJlIGdvaW5nIHRvIGNvbWJpbmVkIHRoaXMgd2l0aCBvdXIgYmVzdCBmaXR0aW5nIG1vZGVsIGRmLCBzbyB3ZSBrbm93IGhvdyB0aGV5IHJhbmtzIGZvciBMT08uDQoNCmBgYHtyfQ0KYmF5ZXNfcmVnX21vZHNfcHJlZGljdGlvbnMgPC0gbGVmdF9qb2luKGJheWVzX3JlZ19tb2RzX3ByZWRpY3Rpb25zLCBiZXN0X2ZpdF9iYXllc19yZWcsIGJ5ID0gYygiaWQiLCAibW9kZWxfdHlwZSIpKQ0KYGBgDQoNCiMjIyDwn5OIIFJlc3VsdHMNCg0KIyMjIyBNb2RlbCBzZWxlY3Rpb24gc3VtbWFyeQ0KDQpJbiBtb3N0IGNhc2VzLCB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gTU88c3ViPjI8L3N1Yj4gYW5kIERPIHdhcyBiZXN0IG1vZGVsbGVkIHdpdGggYSAyXm5kXi1vcmRlciBwb2x5bm9taWFsICgqbiogPSAyMiwgMzglIG9mIGZpc2gpLCBmb2xsb3dlZCBieSBhIDNecmReLW9yZGVyIHBvbHlub21pYWwgKCpuKiA9IDE1LCAyNiUpLCAxXnN0Xi1vcmRlciBwb2x5bm9taWFsICgqbiogPSAxMSwgMTklKSwgYW5kIGZpbmFsbHkgMF50aF4tb3JkZXIgcG9seW5vbWlhbCAoKm4qID0gMTAsIDE3JSkuDQoNCkZvciB0aGUgdHdvIG1vc3QgY29tbW9uIG1vZGVscywgMl5uZF4tIGFuZCAzXnJkXi1vcmRlciBwb2x5bm9taWFscywgdGhpcyBjb3VsZCBzdWdnZXN0IHRoZSBwcmVzZW5jZSBvZiBhIGNyaXRpY2FsIG94eWdlbiB0aHJlc2hvbGQgKFBjcml0KSB3aGVyZSB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gTU88c3ViPjI8L3N1Yj4gYW5kIE88c3ViPjI8L3N1Yj4gY2hhbmdlcy4gVG8gY29uZmlybSB0aGUgcHJlc2VuY2Ugb2YgYSBQY3JpdCwgd2UgbmVlZCB0byB2YWxpZGF0ZWQgdGhlIHNoYXBlIG9mIHRoZSBwb2x5bm9taWFscyAoc2VlIFBjcml0IG1vZGVsIGJlbG93KS4gSW4gYW55IGNhc2UsIHRoZXNlIHR5cGUgb2YgbW9kZWxzIGFyZSBpbmRpY2F0aXZlIG9mICoqb3h5cmVndWxhdG9yKiouDQoNClRoZSBuZXh0IG1vc3QgY29tbW9uIG1vZGVsIHdhcyBpcyAxXnN0Xi1vcmRlciBwb2x5bm9taWFsLiBJbiB0aGUgY2FzZSBvZiB0aGUgMV5zdF4tb3JkZXIgcG9seW5vbWlhbHMsIGl0IHN1Z2dlc3QgdGhlIHByZXNlbmNlcyBvZiBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gbzIgYW5kIE1PMiwgd2hpY2ggaXMgaW5kaWNhdGl2ZSBvZiAqKm94eWNvbmZvcm1lcioqLiBIb3dldmVyLCB0byBiZSB0cnVlIGV2aWRlbmNlIG9mIGEgb3h5Y29uZm9ybWVyIHRoaXMgcmVsYXRpb25zaGlwIHNob3VsZCBiZSBwb3NpdGl2ZSAoaS5lLiBhcyBPPHN1Yj4yPC9zdWI+IGZhbGxzIE1PPHN1Yj4yPC9zdWI+IGFsc28gZmFsbHMpLiAxMyBvZiB0aGUgMTggaW5kaXZpZHVhbHMgYmVzdCBtb2RlbGxlZCB3aXRoIGEgbGluZWFyIGZ1bmN0aW9uIGhhZCBwb3NpdGl2ZSBlc3RpbWF0ZXMgd2l0aCBjcmVkaWJsZSBpbnRlcnZhbHMgdGhhdCBkaWQgbm90IG92ZXJsYXAgd2l0aCB6ZXJvIChUYWJsZSBTMykuDQoNCkxhc3RseSwgMF50aF4tb3JkZXIgd2FzIHRoZSBsZWFzdCBjb21tb24gKCpuKiA9IDMsIDUlKSwgaXQgc3VnZ2VzdHMgdGhhdCBNTzxzdWI+Mjwvc3ViPiBkb2VzIG5vdCBzaG93IGEgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBkZXBlbmRlbmNlIG9uIHRoZSBPPHN1Yj4yPC9zdWI+LiBJbiBvdGhlciB3b3JkcywgdGhlIG1ldGFib2xpYyByYXRlIGRvZXMgbm90IGFkanVzdCBiYXNlZCBvbiBveHlnZW4gYXZhaWxhYmlsaXR5LCBhbmQgdGhlcmUgaXMgbm8gY2xlYXIgY3JpdGljYWwgb3h5Z2VuIHRocmVzaG9sZCAoUGNyaXQpIHdoZXJlIHRoZSByZWxhdGlvbnNoaXAgY2hhbmdlcy4gVGhpcyBpcyBpbmRpY2F0aXZlIG9mIGEgKipveHlyZWd1bGF0b3IqKi4NCg0KYGBge3J9DQpiZXN0X21vZCA8LSBiZXN0X2ZpdF9iYXllc19yZWcgJT4lIA0KICBkcGx5cjo6ZmlsdGVyKGVscGRfbG9vX3JhbmsgPT0gMSkNCg0KdG90YWxfZmlzaCA8LSBucm93KGJlc3RfbW9kKQ0KDQptb2Rfc3VtbWFyeV90YWJsZSA8LSBiZXN0X21vZCAlPiUgDQogIGRwbHlyOjpncm91cF9ieShtb2RlbF90eXBlKSAlPiUgDQogIGRwbHlyOjpyZWZyYW1lKG4gPSBsZW5ndGgoaWQpLA0KICAgICAgICAgICAgICAgICBwZXJjZW50ID0gcm91bmQoKG4vdG90YWxfZmlzaCkqMTAwLDIpKSAlPiUgDQogIGRwbHlyOjptdXRhdGUoYmVzdF9tb2RlbF9uYW1lID0gY2FzZV93aGVuKA0KICAgICAgbW9kZWxfdHlwZSA9PSAibG1fMCIgfiAiMHRoLW9yZGVyIHBvbHlub21pYWwiLA0KICAgICAgbW9kZWxfdHlwZSA9PSAibG1fMSIgfiAiMXN0LW9yZGVyIHBvbHlub21pYWwiLA0KICAgICAgbW9kZWxfdHlwZSA9PSAibG1fMiIgfiAiMm5kLW9yZGVyIHBvbHlub21pYWwiLA0KICAgICAgbW9kZWxfdHlwZSA9PSAibG1fMyIgfiAiM3JkLW9yZGVyIHBvbHlub21pYWwiLA0KICAgICAgVFJVRSB+ICJFUlJPUiINCiAgICApKQ0KDQoNCnRhYmxlX2J3bSA8LSBtb2Rfc3VtbWFyeV90YWJsZSAlPiUgDQogIGRwbHlyOjpzZWxlY3QoYmVzdF9tb2RlbF9uYW1lLCBldmVyeXRoaW5nKCksIC1tb2RlbF90eXBlKSAlPiUgDQogICBndCgpICU+JSANCiAgY29sc19hbGlnbigNCiAgICBhbGlnbiA9ICJjZW50ZXIiLCANCiAgICBjb2x1bW5zID0gZXZlcnl0aGluZygpDQogICkNCg0KdGFibGVfYndtDQpgYGANCg0KU3VtbWFyeSBvZiBmaXNoIGJlc3QgbW9kZWwgd2l0aCBhIGxpbmVhciBmdW5jdGlvbi4NCg0KIyMjIFRhYmxlIFMzDQoNCioqVGFibGUgUzM6KiogVGVuIGZpc2ggdGhhdCB3ZXJlIGJlc3QgbW9kZWxsZWQgd2l0aCBhIGxpbmVhciBmdW5jdGlvbiwgc2hvd2luZyByXjJeLCBhbmQgZXN0aW1hdGUgKCkuIE9ubHkgdHdvIGZpc2ggaGFkIHBvc2l0aXZlIGVzdGltYXRlcyB3aXRoIGNyZWRpYmxlIGludGVydmFscyB0aGF0IGRpZCBub3Qgb3ZlcmxhcCB3aXRoIHplcm8sIHdoaWNoIGFyZSBoaWdobGlnaHRlZCBhcyBjb25mb3JtaW5nIGluIHRoZSB0YWJsZS4gVGh1cyBpbiB0b3RhbCwgMTMgb2YgNTggZmlzaCBzaG93ZWQgc3VmZmljaWVudCBldmlkZW5jZSB0byBiZSBjb25mb3JtaW5nLg0KDQpgYGB7cn0NCnRhYmxlX2xtXzEgPC0gYmVzdF9tb2QgJT4lIA0KICBkcGx5cjo6ZmlsdGVyKG1vZGVsX3R5cGUgPT0gImxtXzEiKSAlPiUgDQogIGRwbHlyOjptdXRhdGUocl9zcV9jaSA9IHBhc3RlMChmb3JtYXQocm91bmQocjIsIDMpLCBzY2llbnRpZmljID0gRkFMU0UpLCAiICgiLCANCiAgICAgICAgICAgICAgICAgICBmb3JtYXQocm91bmQocjJfcTIuNSwgMyksIHNjaWVudGlmaWMgPSBGQUxTRSksICIgdG8gIiwgDQogICAgICAgICAgICAgICAgICAgZm9ybWF0KHJvdW5kKHIyX3E5Ny41LCAzKSwgc2NpZW50aWZpYyA9IEZBTFNFKSwgIikiKSwNCiAgZXN0X2NpID0gcGFzdGUwKGZvcm1hdChyb3VuZChlc3RpbWF0ZV9ETywgNCksIHNjaWVudGlmaWMgPSBGQUxTRSksICIgKCIsIA0KICAgICAgICAgICAgICAgICAgZm9ybWF0KHJvdW5kKGNvbmYubG93X0RPLCA0KSwgc2NpZW50aWZpYyA9IEZBTFNFKSwgIiB0byAiLCANCiAgICAgICAgICAgICAgICAgIGZvcm1hdChyb3VuZChjb25mLmhpZ2hfRE8sIDQpLCBzY2llbnRpZmljID0gRkFMU0UpLCAiKSIpLA0KICAgICAgICAgICAgICAgIGNvbmZvcm1lciA9IGlmX2Vsc2UoY29uZi5sb3dfRE8gPiAwLCAiQ29uZm9ybWluZyIsICJOb3QgY29uZm9ybWluZyIpKSAlPiUgDQogIGRwbHlyOjpzZWxlY3QoaWQsIGVzdGltYXRlX0RPLCByX3NxX2NpLCBlc3RfY2ksIGNvbmZvcm1lcikgJT4lIA0KICBkcGx5cjo6YXJyYW5nZShjb25mb3JtZXIsIGRlc2MoZXN0X2NpKSkgJT4lIA0KICBkcGx5cjo6dW5ncm91cCgpDQoNCmZpcnN0X29yZGVyX2lkcyA8LSB0YWJsZV9sbV8xICU+JSANCiAgZGlzdGluY3QoaWQpICU+JSANCiAgcHVsbCguKQ0KDQptZWFuX21vMiA8LSBzbG9wZV90aWR5ICU+JSANCiAgZHBseXI6OmZpbHRlcihpZCAlaW4lIGZpcnN0X29yZGVyX2lkcykgJT4lIA0KICBkcGx5cjo6Z3JvdXBfYnkoaWQpICU+JSANCiAgZHBseXI6OnJlZnJhbWUobWVhbl9NTzJfZyA9IG1lYW4oTU8yX2csIG5hLnJtID0gVFJVRSkpDQoNCnRhYmxlX2xtXzEgPC0gbGVmdF9qb2luKHRhYmxlX2xtXzEsIG1lYW5fbW8yLCBieSA9ICJpZCIpIA0KDQp0YWJsZV9sbV8xIDwtICB0YWJsZV9sbV8xICU+JSANCiAgZHBseXI6Om11dGF0ZShwZXJjZW50X2NoYW5nZSA9IChlc3RpbWF0ZV9ETy9tZWFuX01PMl9nKSoxMDApICU+JSANCiAgZHBseXI6OnNlbGVjdChpZCwgcl9zcV9jaSwgZXN0X2NpLCBwZXJjZW50X2NoYW5nZSwgY29uZm9ybWVyKQ0KDQoNCnRhYmxlX2xtXzEgJT4lIA0KICBndCgpICU+JSANCiAgY29sc19hbGlnbigNCiAgICBhbGlnbiA9ICJjZW50ZXIiLCANCiAgICBjb2x1bW5zID0gZXZlcnl0aGluZygpDQogICkgJT4lIA0KICBjb2xzX2xhYmVsKA0KICAgIGlkID0gIkZpc2ggSUQiLA0KICAgIHJfc3FfY2kgPSAicjIgKENJKSIsDQogICAgZXN0X2NpID0gIkVzdGltYXRlIChDSSkiLA0KICAgIHBlcmNlbnRfY2hhbmdlID0gIlBlcmNlbnRhZ2UgY2hhbmdlIiwNCiAgICBjb25mb3JtZXIgPSAiRXZpZGVuY2Ugb2Ygb3h5Y29uZm9ybWluZyINCiAgKQ0KYGBgDQoNCiMjIyMgUGxvdGluZyBhbGwgbW9kZWxzDQoNCkRhdGEgc2V0IHdpdGggYWxsIHNsb3BlcyBhbmQgd2hpY2ggbW9kZWwgd2FzIGJlc3QNCg0KYGBge3J9DQpiZXN0X2ZpdCA8LSBsZWZ0X2pvaW4oc2xvcGVfdGlkeSwgYmVzdF9tb2QsIGJ5ID0gImlkIikNCmBgYA0KDQpTYXZpbmcgYWxsIHJlZ3Jlc3Npb24sIGFuZCBoaWdobGlnaHRpbmcgdGhlIG1vZGVsIHRoYXQgaGFzIHRoZSBiZXN0IGZpdCwgYmFzZWQgb24gQUlDIHZhbHVlcy4gVGhpcyBpcyBjYWxsZWQgYGNvbWJpbmVkX3JlZ19wbG90cy5wZGZgDQoNCmBgYHtyLCBmaWcuaGVpZ2h0ID0gMywgZmlnLndpZHRoPSA0fQ0KIyAjIENyZWF0ZSBhIGxpc3QgdG8gc3RvcmUgdGhlIHBsb3RzDQojIHBsb3RzIDwtIGxpc3QoKQ0KIyBtb2RlbF9wcmVkc19saXN0IDwtIGxpc3QoKQ0KIyBpbmNyZW1lbnRhbF9yZWdfYmF5ZXNfd2QgPC0gcGFzdGUwKG91dHB1dF9maWdfd2QsICIuL2luY3JlbWVudGFsX3JlZ3Jlc3Npb25zIikNCiMgDQojIGZvciAoaWRfaSBpbiBpZHMpIHsNCiMgICANCiMgICAjIEZpbHRlciBkYXRhIGZvciB0aGUgY3VycmVudCBJRA0KIyAgIGRmX2kgPC0gYmF5ZXNfcmVnX21vZHNfcHJlZGljdGlvbnMgJT4lDQojICAgICBkcGx5cjo6ZmlsdGVyKGlkID09IGlkX2kpICU+JSANCiMgICAgIGRwbHlyOjptdXRhdGUobGluZV9zaXplID0gaWZfZWxzZShlbHBkX2xvb19yYW5rID09IDEsIDIsIDEpLA0KIyAgICAgICAgICAgIGFscGhhX3ZhbHVlID0gaWZfZWxzZShlbHBkX2xvb19yYW5rID09IDEsIDEsIDAuNCkpDQojICAgDQojICAgeF9taW4gPC0gZGZfaSAlPiUNCiMgICAgIGRwbHlyOjpyZWZyYW1lKG1pbiA9IG1pbihETyksIG5hLnJtID0gVFJVRSkgJT4lIA0KIyAgICAgZHBseXI6OnB1bGwobWluKQ0KIyAgIA0KIyAgIHlfbWF4IDwtIGRmX2kgJT4lDQojICAgICBkcGx5cjo6cmVmcmFtZShtYXggPSBtYXgoTU8yX2cpLCBuYS5ybSA9IFRSVUUpICU+JSANCiMgICAgIGRwbHlyOjpwdWxsKG1heCkNCiMgICANCiMgICBiZXN0X3dlaWdodGVkX21vZGVsX2kgPC0gYmVzdF9maXRfYmF5ZXNfcmVnICU+JSANCiMgICAgIGRwbHlyOjpmaWx0ZXIoaWQgPT0gaWRfaSAmIGVscGRfbG9vX3JhbmsgPT0gMSkNCiMgICANCiMgICBwb2x5X2lfbmFtZSA8LSBiZXN0X3dlaWdodGVkX21vZGVsX2kgJT4lDQojICAgICBkcGx5cjo6bXV0YXRlKG5hbWUgPSBjYXNlX3doZW4oDQojICAgICAgIG1vZGVsX3R5cGUgPT0gImxtXzAiIH4gIjB0aC1vcmRlciIsDQojICAgICAgIG1vZGVsX3R5cGUgPT0gImxtXzEiIH4gIjFzdC1vcmRlciIsDQojICAgICAgIG1vZGVsX3R5cGUgPT0gImxtXzIiIH4gIjJuZC1vcmRlciIsDQojICAgICAgIG1vZGVsX3R5cGUgPT0gImxtXzMiIH4gIjNyZC1vcmRlciIsDQojICAgICAgIFRSVUUgfiAiRVJST1IiDQojICAgICApKSAlPiUgDQojICAgICBkcGx5cjo6cHVsbChuYW1lKQ0KIyAgIA0KIyAgIHJfaSA8LSBiZXN0X3dlaWdodGVkX21vZGVsX2kgJT4lIA0KIyAgICAgZHBseXI6Om11dGF0ZShyX3NxX2NpID0gcGFzdGUwKHJvdW5kKHIyLCAzKSwgIiAoIiwgDQojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kKHIyX3EyLjUsIDMpLCAi4oCTIiwgDQojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kKHIyX3E5Ny41LCAzKSwgIikiKSkgJT4lIA0KIyAgICAgZHBseXI6OnB1bGwocl9zcV9jaSkNCiMgDQojICAgIyBDcmVhdGUgdGhlIHBsb3QNCiMgICBwbG90X2kgPC0gZ2dwbG90KCkgKw0KIyAgICAgZ2VvbV9yaWJib24oZGF0YSA9IGRmX2ksDQojICAgICAgICAgICAgICAgICBhZXMoeCA9IERPLCB5ID0gcHJlZGljdGVkLCB5bWluID0gcHJlZF9sb3dlciwgeW1heCA9IHByZWRfdXBwZXIsIGZpbGwgPSBtb2RlbF90eXBlKSwNCiMgICAgICAgICAgICAgICAgIGFscGhhID0gMC4xKSArDQojICAgICBnZW9tX2xpbmUoZGF0YSA9IGRmX2ksIA0KIyAgICAgICAgICAgICAgIGFlcyh4ID0gRE8sIHkgPSBwcmVkaWN0ZWQsIGNvbG91ciA9IG1vZGVsX3R5cGUsIGxpbmV3aWR0aCA9IGxpbmVfc2l6ZSwgYWxwaGEgPSBhbHBoYV92YWx1ZSkpICsNCiMgICAgIGdlb21fcG9pbnQoZGF0YSA9IGRmX2kgJT4lIGRwbHlyOjpmaWx0ZXIoZWxwZF9sb29fcmFuayA9PSAxKSwgYWVzKHggPSBETywgeSA9IE1PMl9nKSwgYWxwaGEgPSAwLjYsIGNvbG91ciA9ICJibGFjayIsIHNpemUgPSAyKSArDQojICAgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoInJlZCIsICJibHVlIiwgImdyZWVuIiwgInB1cnBsZSIpLCANCiMgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiMHRoIE9yZGVyIiwgIjFzdCBPcmRlciIsICIybmQgT3JkZXIiLCAiM3JkIE9yZGVyIikpICsNCiMgICAgIHNjYWxlX3NpemVfaWRlbnRpdHkoKSArICAjIFVzZSB0aGUgc2l6ZSB2YWx1ZXMgZGlyZWN0bHkNCiMgICAgIHNjYWxlX2FscGhhX2lkZW50aXR5KGd1aWRlID0gIm5vbmUiKSArICAjIFJlbW92ZSB0aGUgYWxwaGEgbGVnZW5kIA0KIyAgICAgYW5ub3RhdGUoInRleHQiLCB4ID0geF9taW4sIA0KIyAgICAgICAgICAgICAgeSA9IHlfbWF4LCANCiMgICAgICAgICAgICAgIGxhYmVsID0gcGFzdGUwKCJCZXN0IGZpdDogIixwb2x5X2lfbmFtZSwgIlxuIiwgInIyID0gIiwgcl9pKSwgDQojICAgICAgICAgICAgICBoanVzdCA9IDAsIHZqdXN0ID0gMSwgc2l6ZSA9IDQpICsNCiMgICAgIGxhYnMoDQojICAgICAgIHRpdGxlID0gcGFzdGUoaWRfaSksDQojICAgICAgIHggPSAiRGlzc29sdmVkIG94eWdlbiBwZXJjZW50YWdlIChETykiLA0KIyAgICAgICB5ID0gIk1PMiAobzIgbWcvZy9oKSIsDQojICAgICAgIGNvbG91ciA9ICJNb2RlbCIpICsNCiMgICAgIHRoZW1lX2NsYXNzaWMoKSArDQojICAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQojICAgDQojICAgIyBTdG9yZSB0aGUgcGxvdA0KIyAgIHBsb3RzW1tpZF9pXV0gPC0gcGxvdF9pDQojICAgDQojICAgcHJpbnQocGxvdF9pKQ0KIyB9DQojIA0KIyANCiMgcGRmKGZpbGUgPSBwYXN0ZTAoaW5jcmVtZW50YWxfcmVnX2JheWVzX3dkLCAiLi9jb21iaW5lZF9yZWdfcGxvdHMucGRmIiksIHdpZHRoID0gOCwgaGVpZ2h0ID0gNikNCiMgDQojIGRldi5vZmYoKSAgIyBDbG9zZSB0aGUgUERGIGRldmljZQ0KYGBgDQoNCkdldHRpbmcgYSBwbG90IGZvciBlYWNoIGJlc3QgZml0IHJlZ3Jlc3Npb24sIGFuZCBvdmVybGF5aW5nIGEgZ2xvYmFsIG1vZGVsIGZvciB0aGF0IG1vZGVsIHR5cGUuDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0Kb3V0cHV0X21vZHNfYmF5ZXNfZ2xvYmFsX3dkIDwtIHBhc3RlMChvdXRwdXRfbW9kc193ZCwgIi4vYmF5ZXMtcmVncy1nbG9iYWwiKQ0KYGBgDQoNCkhlcmUgd2UgYXJlIGdyb3VwaW5nIGZpc2ggYnkgYmVzdCBmaXR0aW5nIG1vZGVsIGFuZCBnZXR0aW5nIGFuIGF2ZXJhZ2UgdHJlbmQuIEkgaGF2ZSBoYXNoZWQgdGhlIGNvZGUgc28geW91IGRvbid0IG5lZWQgdG8gcmUtcnVuIHRoZSBtb2RlbHMNCg0K4o+t77iPICoqU2tpcCB0aGlzIHN0ZXAqKiBpZiB5b3UgaGF2ZSBkb3dubG9hZGVkIHRoZSBnbG9iYWwgbW9kZWxzICoqJy5yZHMnKiogaW4gdGhlICdiYXllcy1yZWdzLWdsb2JhbCcgZm9sZGVyDQoNCmBgYHtyfQ0KIyBzZWVkX251bWJlciA9IDE0MzAxOQ0KIyANCiMgIyBTZXQgdXAgcGFyYWxsZWwgYmFja2VuZA0KIyBmdXR1cmU6OnBsYW4obXVsdGlzZXNzaW9uLCB3b3JrZXJzID0gNCkgICMgQWRqdXN0IHdvcmtlcnMgYmFzZWQgb24gc3lzdGVtIHJlc291cmNlcw0KIyANCiMgIyBEZWZpbmUgbW9kZWwgZm9ybXVsYXMgYW5kIGRhdGENCiMgbW9kZWxfZm9ybXVsYXMgPC0gbGlzdCgNCiMgICBsbV8wID0gYmYoTU8yX2cgfiAxLCBmYW1pbHkgPSBnYXVzc2lhbigpKSwNCiMgICBsbV8xID0gYmYoTU8yX2cgfiBETywgZmFtaWx5ID0gZ2F1c3NpYW4oKSksDQojICAgbG1fMiA9IGJmKE1PMl9nIH4gcG9seShETywgMiksIGZhbWlseSA9IGdhdXNzaWFuKCkpLA0KIyAgIGxtXzMgPSBiZihNTzJfZyB+IHBvbHkoRE8sIDMpLCBmYW1pbHkgPSBnYXVzc2lhbigpKQ0KIyApDQojIA0KIyBtb2RlbF9kYXRhIDwtIGxpc3QoDQojICAgbG1fMCA9IGJlc3RfZml0ICU+JSBmaWx0ZXIobW9kZWxfdHlwZSA9PSAibG1fMCIpLA0KIyAgIGxtXzEgPSBiZXN0X2ZpdCAlPiUgZmlsdGVyKG1vZGVsX3R5cGUgPT0gImxtXzEiKSwNCiMgICBsbV8yID0gYmVzdF9maXQgJT4lIGZpbHRlcihtb2RlbF90eXBlID09ICJsbV8yIiksDQojICAgbG1fMyA9IGJlc3RfZml0ICU+JSBmaWx0ZXIobW9kZWxfdHlwZSA9PSAibG1fMyIpDQojICkNCiMgDQojICMgUnVuIG1vZGVscyBpbiBwYXJhbGxlbCB3aXRoIGZ1dHVyZV9tYXAoKQ0KIyBtb2RlbHMgPC0gZnV0dXJlX21hcChuYW1lcyhtb2RlbF9mb3JtdWxhcyksIH57DQojICAgYnJtKA0KIyAgICAgZm9ybXVsYSA9IG1vZGVsX2Zvcm11bGFzW1sueF1dLA0KIyAgICAgZGF0YSA9IG1vZGVsX2RhdGFbWy54XV0sDQojICAgICBjb3JlcyA9IDQsDQojICAgICBzZWVkID0gc2VlZF9udW1iZXIsDQojICAgICBzYXZlX3BhcnMgPSBzYXZlX3BhcnMoYWxsID0gVFJVRSksDQojICAgICBzYW1wbGVfcHJpb3IgPSBGQUxTRSwNCiMgICAgIHNpbGVudCA9IFRSVUUsDQojICAgICBmaWxlID0gcGFzdGUwKG91dHB1dF9tb2RzX2JheWVzX2dsb2JhbF93ZCwgIi4vIiwgLngsICJfZ2xvYmFsIikNCiMgICApDQojIH0pDQojIA0KIyAjIEFzc2lnbiBtb2RlbCBuYW1lcyB0byByZXN1bHRzDQojIG5hbWVzKG1vZGVscykgPC0gbmFtZXMobW9kZWxfZm9ybXVsYXMpDQojIA0KIyAjIFN0b3AgcGFyYWxsZWwgcGxhbiBhZnRlciBleGVjdXRpb24NCiMgZnV0dXJlOjpwbGFuKHNlcXVlbnRpYWwpDQpgYGANCg0K4o+t77iPICoqU2tpcCB0aGlzIHN0ZXAqKiBpZiB5b3UgaGF2ZSBkb3dubG9hZGVkIHRoZSBnbG9iYWxfbW9kZWxzX3ByZWRfZGYuY3N2DQoNCmBgYHtyfQ0KIyBnbG9iYWxfbW9kZWxzX3ByZWRzIDwtIGxpc3QoKQ0KIyANCiMgZm9yIChtb2RlX25hbWUgaW4gbmFtZXMoYmF5ZXNfcmVnX21vZHNfZ2xvYmFsKSkgew0KIyAgIA0KIyAgIG1vZF9pIDwtIGJheWVzX3JlZ19tb2RzX2dsb2JhbFtbbW9kZV9uYW1lXV0NCiMgICBtb2RlX3R5cGUgPSBzdHJfcmVtb3ZlKG1vZGVfbmFtZSwgIl9nbG9iYWwiKQ0KIyAgIA0KIyAgICBtb2RlbF9wcmVkaWN0aW9uc19pIDwtIGFzLmRhdGEuZnJhbWUoZml0dGVkKG1vZF9pLCBzdW1tYXJ5ID0gVFJVRSkpICU+JSANCiMgICAgICAgZHBseXI6Om11dGF0ZShtb2RlbCA9IG1vZGVfbmFtZSwNCiMgICAgICAgICAgICAgICAgICAgICBtb2RlbF90eXBlID0gbW9kZV90eXBlKSAlPiUgDQojICAgICAgIGRwbHlyOjpyZW5hbWUocHJlZF9sb3dlciA9IFEyLjUsIHByZWRfdXBwZXIgPSBROTcuNSwgcHJlZGljdGVkID0gRXN0aW1hdGUsIHByZWRfZXJyb3IgPSBFc3QuRXJyb3IpICU+JSANCiMgICAgICAgZHBseXI6OnNlbGVjdChtb2RlbCwgZXZlcnl0aGluZygpKQ0KIyAgICANCiMgICAgb3JpZ2luYWxfZGF0YV9pIDwtIGJlc3RfZml0ICU+JSBmaWx0ZXIobW9kZWxfdHlwZSA9PSBtb2RlX3R5cGUpICU+JSANCiMgICAgICBkcGx5cjo6c2VsZWN0KC1tb2RlbF90eXBlKQ0KIyAgICAgDQojICAgICBtb2RlbF9wcmVkaWN0aW9uc19vcmlnaW5hbF9pIDwtIGNiaW5kKG1vZGVsX3ByZWRpY3Rpb25zX2ksIG9yaWdpbmFsX2RhdGFfaSkNCiMgICAgIA0KIyAgICANCiMgICAgZ2xvYmFsX21vZGVsc19wcmVkc1tbbW9kZV9uYW1lXV0gPC0gbW9kZWxfcHJlZGljdGlvbnNfb3JpZ2luYWxfaQ0KIyB9DQojIA0KIyBnbG9iYWxfbW9kZWxzX3ByZWRfZGYgPC0gYmluZF9yb3dzKGdsb2JhbF9tb2RlbHNfcHJlZHMpDQojIA0KIyB3cml0ZS5jc3YoZ2xvYmFsX21vZGVsc19wcmVkX2RmLCAgcGFzdGUwKG1vZF9kYXRhX3dkLCAiLy5nbG9iYWxfbW9kZWxzX3ByZWRfZGYuY3N2IiksIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQoNCkxvYWQgZGF0YSBmcmFtZQ0KDQpgYGB7cn0NCmdsb2JhbF9tb2RlbHNfcHJlZF9kZiA8LSByZWFkLmNzdihwYXN0ZTAobW9kX2RhdGFfd2QsICIvLmdsb2JhbF9tb2RlbHNfcHJlZF9kZi5jc3YiKSkNCmBgYA0KDQojIyMjIEZpZ3VyZSBTNQ0KDQpCZXN0IGZpdCByZWdyZXNzaW9ucyB3aXRoIGdsb2JhbCBtb2RlbHMgYmFzZWQgb24gdGhhdCBwb2x5bm9taWFsIG9yZGVyLg0KDQpgYGB7cn0NCmdsb2JhbF9tb2RlbHNfcHJlZF9kZiA8LSBnbG9iYWxfbW9kZWxzX3ByZWRfZGYgJT4lDQogIGRwbHlyOjptdXRhdGUobW9kZWxfbmFtZSA9IGNhc2Vfd2hlbigNCiAgICAgIG1vZGVsX3R5cGUgPT0gImxtXzAiIH4gIjB0aC1vcmRlciBwb2x5bm9taWFsIiwNCiAgICAgIG1vZGVsX3R5cGUgPT0gImxtXzEiIH4gIjFzdC1vcmRlciBwb2x5bm9taWFsIiwNCiAgICAgIG1vZGVsX3R5cGUgPT0gImxtXzIiIH4gIjJuZC1vcmRlciBwb2x5bm9taWFsIiwNCiAgICAgIG1vZGVsX3R5cGUgPT0gImxtXzMiIH4gIjNyZC1vcmRlciBwb2x5bm9taWFsIiwNCiAgICAgIFRSVUUgfiAiRVJST1IiDQogICAgKSkNCg0KYW5ub3RhdGlvbl9kYXRhIDwtIG1vZF9zdW1tYXJ5X3RhYmxlICU+JQ0KICBkcGx5cjo6c2VsZWN0KG1vZGVsX3R5cGUsIGJlc3RfbW9kZWxfbmFtZSwgbikNCg0KYmF5ZXNfcmVnX21vZHNfcHJlZGljdGlvbnNfYmVzdCA8LSBiYXllc19yZWdfbW9kc19wcmVkaWN0aW9ucyAlPiUgDQogIGRwbHlyOjpmaWx0ZXIoZWxwZF9sb29fcmFuayA9PSAxKSANCg0KZmlnX3M1IDwtIGdncGxvdCgpICsNCiAgZ2VvbV9saW5lKGRhdGEgPSBiYXllc19yZWdfbW9kc19wcmVkaWN0aW9uc19iZXN0LA0KICAgICAgICAgICAgYWVzKHggPSBETywgeSA9IHByZWRpY3RlZCwgY29sb3IgPSBpZCksIHNpemUgPSAxKSArDQogICMgZ2VvbV9zbW9vdGgoZGF0YSA9IGJlc3RfZml0LA0KICAjICAgICAgICAgICBhZXMoeCA9IERPLCB5ID0gTU8yX2csIGNvbG9yID0gaWQpLCBzaXplID0gMSwgYWxwaGEgPSAxLCBzZSA9IEZBTFNFKSArDQogIGdlb21fcmliYm9uKGRhdGEgPSBnbG9iYWxfbW9kZWxzX3ByZWRfZGYsDQogICAgICAgICAgICAgIGFlcyh4ID0gRE8sIHltaW4gPSBwcmVkX2xvd2VyDQosIHltYXggPSBwcmVkX3VwcGVyLCBncm91cCA9IG1vZGVsKSwNCiAgICAgICAgICAgICAgZmlsbCA9ICIjRkM2Qzg1IiwgYWxwaGEgPSAwLjIpICsgICMgU2hhZGVkIGNvbmZpZGVuY2UgaW50ZXJ2YWxzDQogIGdlb21fbGluZShkYXRhID0gZ2xvYmFsX21vZGVsc19wcmVkX2RmLA0KICAgICAgICAgICAgYWVzKHggPSBETywgeSA9IHByZWRpY3RlZCksIGxpbmV3aWR0aCA9IDEuNSwgY29sb3IgPSAiI0ZGMDA3RiIpICsNCiAgZmFjZXRfd3JhcCh+bW9kZWxfdHlwZSkgKw0KICBzY2FsZV9jb2xvcl9ncmV5KHN0YXJ0ID0gMC4xLCBlbmQgPSAwLjkpICsNCiAgbGFicygNCiAgICAgIHRpdGxlID0gcGFzdGUoIkJlc3QgZml0IHJlZ3Jlc3Npb25zIGdyb3VwZWQgYnkgcG9seW5vbWlhbCBvcmRlciIpLA0KICAgICAgeCA9ICJEaXNzb2x2ZWQgb3h5Z2VuIHBlcmNlbnRhZ2UgKERPKSIsDQogICAgICB5ID0gIk1PMiAoTzIgbWcvZy9oKSIpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogIGdlb21fdGV4dChkYXRhID0gYW5ub3RhdGlvbl9kYXRhLA0KICAgICAgICAgICAgYWVzKHggPSAtSW5mLCB5ID0gSW5mLCBsYWJlbCA9IHBhc3RlMCgiaXRhbGljKG4pID09ICIsIG4pKSwNCiAgICAgICAgICAgIGhqdXN0ID0gLTAuMSwgdmp1c3QgPSAxLjIsIGluaGVyaXQuYWVzID0gRkFMU0UsIHBhcnNlID0gVFJVRSkNCmZpZ19zNQ0KYGBgDQoNCioqRmlndXJlIFM1OioqIEluZGl2aWR1YWwgcmVncmVzc2lvbiBjdXJ2ZXMgc2hvd2luZyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gbWFzcy1zcGVjaWZpYyBveHlnZW4gY29uc3VtcHRpb24gcmF0ZSAo4bmAT+KCgjsgbWfigbvCuSBP4oKCIGjigbvCuSkgYW5kIGFtYmllbnQgZGlzc29sdmVkIG94eWdlbiAoRE87ICUgc2F0dXJhdGlvbiksIGdyb3VwZWQgYnkgdGhlIGJlc3QtZml0dGluZyBwb2x5bm9taWFsIG9yZGVyICgw4bWXyrAgdG8gM8qz4bWIKS4gRWFjaCBwYW5lbCByZXByZXNlbnRzIGZpc2ggd2hvc2Ug4bmAT+KCguKAk0RPIHJlbGF0aW9uc2hpcCB3YXMgYmVzdCBtb2RlbGxlZCBieSB0aGF0IHBvbHlub21pYWwgb3JkZXIsIGJhc2VkIG9uIGxlYXZlLW9uZS1vdXQgY3Jvc3MtdmFsaWRhdGlvbiAoTE9PLUNWKS4gR3JleSBsaW5lcyByZXByZXNlbnQgaW5kaXZpZHVhbCBtb2RlbCBmaXRzOyB0aGUgYm9sZCBwaW5rIGxpbmUgc2hvd3MgdGhlIGdyb3VwLWxldmVsIHRyZW5kIHdpdGhpbiBlYWNoIHBvbHlub21pYWwgY2xhc3MuIEZpc2ggd2VyZSBtb3N0IGNvbW1vbmx5IGJlc3QgZml0IGJ5IGEgMuKBv+G1iC1vcmRlciBwb2x5bm9taWFsIChuID0gMjIpLCBmb2xsb3dlZCBieSAzyrPhtYgtb3JkZXIgKCpuKiA9IDE1KSwgMcui4bWXLW9yZGVyICgqbiogPSAxMSksIGFuZCAw4bWXyrAtb3JkZXIgKCoqbiA9IDEwKS4gSGlnaGVyLW9yZGVyIGZpdHMgKDLigb/htYggYW5kIDPKs+G1iCkgYW5kIDDhtZfKsC1vcmRlciBmaXRzIGFyZSBnZW5lcmFsbHkgaW5kaWNhdGl2ZSBvZiBveHlyZWd1bGF0aW5nIHJlc3BvbnNlcywgd2hpbGUgMcui4bWXLW9yZGVyIGZpdHMgbWF5IHN1Z2dlc3Qgb3h5Y29uZm9ybWluZyBiZWhhdmlvdXIgd2hlbiBwb3NpdGl2ZWx5IHNsb3BlZC4gIA0KDQoNCmBgYHtyfQ0KIyBnZ3NhdmUoZmlsZW5hbWUgPSBwYXN0ZTAob3V0cHV0X2ZpZ193ZCwgIi4vbXNfZmlndXJlcy4vZmlndXJlLTIucGRmIiksIA0KIyAgICAgICAgcGxvdCA9IGZpZ18yLA0KIyAgICAgICAgd2lkdGggPSAyMTAsDQojICAgICAgICBoZWlnaHQgPSAyOTcvMiwgICMgU3BlY2lmeSB0aGUgaGVpZ2h0IG9mIHRoZSBwbG90DQojICAgICAgICB1bml0cyA9ICJtbSIpDQpgYGANCg0KIyMgT+KCgmNyaXQgbW9kZWwNCg0KV2Ugd2lsbCBjYWxjdWxhdGUgT+KCgmNyaXQgdXNpbmcgQ2hhYm90IG1ldGhvZCBhbmQgZnVuY3Rpb24gYGNhbGNPMmNyaXRgLiAgDQoNClRoaXMgZnVuY3Rpb24gdXNlcyB0aGUgZmlmdGggcGVyY2VudGlsZSBvZiB0aGUgTU88c3ViPjI8L3N1Yj4gdmFsdWVzIG9ic2VydmVkIGF0IGRpc3NvbHZlZCBveHlnZW4gbGV2ZWxzIOKJpSA4MCUgYWlyIHNhdHVyYXRpb24gYXMgdGhlIGNyaXRlcmlvbiB0byBhc3Nlc3MgbG93IE1PPHN1Yj4yPC9zdWI+IHZhbHVlcy4gVGhlIGFsZ29yaXRobSB0aGVuIGlkZW50aWZpZXMgYWxsIHRoZSBNTzxzdWI+Mjwvc3ViPiBtZWFzdXJlbWVudHMgZ3JlYXRlciB0aGFuIHRoaXMgbWluaW1hbGx5IGFjY2VwdGFibGUgTU88c3ViPjI8L3N1Yj4gdmFsdWUuIFdpdGhpbiB0aGlzIHN1Yi1zZXQsIGl0IGlkZW50aWZpZXMgdGhlIE1PPHN1Yj4yPC9zdWI+MiBtZWFzdXJlbWVudCBtYWRlIGF0IHRoZSBsb3dlc3QgRE8gYW5kIHRoZXJlYWZ0ZXIgY29uc2lkZXJzIHRoaXMgRE8gYXMgY2FuZGlkYXRlIGZvciBicmVha3BvaW50IChuYW1lZCBwaXZvdERPIGluIHRoZSBzY3JpcHQpLiBBIHJlZ3Jlc3Npb24gaXMgdGhlbiBjYWxjdWxhdGVkIHVzaW5nIG9ic2VydmF0aW9ucyBhdCBETyBsZXZlbHMgXDwgcGl2b3RETywgYW5kIGEgZmlyc3QgZXN0aW1hdGUgb2YgTzxzdWI+MmNyaXQ8L3N1Yj4gaXMgY2FsY3VsYXRlZCBhcyB0aGUgaW50ZXJzZWN0aW9uIG9mIHRoaXMgcmVncmVzc2lvbiBsaW5lIHdpdGggdGhlIGhvcml6b250YWwgbGluZSByZXByZXNlbnRpbmcgU01SLiBUaGUgc2NyaXB0IHRoZW4gZ29lcyB0aHJvdWdoIHZhbGlkYXRpb24gc3RlcHMgdG8gZW5zdXJlIHRoYXQgdGhlIHNsb3BlIG9mIHRoZSByZWdyZXNzaW9uIGlzIG5vdCBzbyBsb3cgdGhhdCB0aGUgbGluZSwgcHJvamVjdGVkIHRvIG5vcm1veGljIERPIGxldmVscywgcGFzc2VzIGJlbG93IGFueSBNTzxzdWI+Mjwvc3ViPiB2YWx1ZXMgb2JzZXJ2ZWQgaW4gbm9ybW94aWEuIEl0IGFsc28gZW5zdXJlcyB0aGF0IHRoZSBpbnRlcmNlcHQgaXMgbm90IGdyZWF0ZXIgdGhhbiB6ZXJvLiBDb3JyZWN0aXZlIG1lYXN1cmVzIGFyZSB0YWtlbiBpZiBzdWNoIHByb2JsZW1zIGFyZSBlbmNvdW50ZXJlZC4gIA0KDQpsb3dlc3RNTzIgZGVmYXVsdCBpcyB0aGUgYHF1YW50aWxlKE1PMltETyA+PSA4MF0sIHA9MC4wNSlgLiBJdCBpcyB1c2VkIHRvIHNlZ21lbnQgdGhlIGRhdGEgYW5kIGxvY2F0ZSB0aGUgcGl2b3RETy4gIA0KDQpgYGB7cn0NCmlkcyA8LSBzbG9wZV90aWR5ICU+JSANCiAgZHBseXI6OmRpc3RpbmN0KGlkKSAlPiUgDQogIGRwbHlyOjpwdWxsKCkNCg0KcGNyaXRfbW9kZWxfZGZfbGlzdCA8LSBsaXN0KCkNCnBjcml0X21vZGVscyA8LSAgbGlzdCgpDQoNCmZvciAoaWRfaSBpbiBpZHMpIHsNCg0KZGZfaSA8LSBzbG9wZV90aWR5ICU+JSANCiAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKQ0KDQpvMmNyaXQgPC0gY2FsY08yY3JpdChEYXRhID0gZGZfaSwgU01SID0gZGZfaSRTTVJbMV0sIGxvd2VzdE1PMj1OQSwgZ2FwTGltaXQgPSA0LA0KICAgICAgICAgICAgICAgICAgICAgbWF4Lm5iLk1PMi5mb3IucmVnID0gNykNCg0KYmVzdF9tb2RfdHlwZSA8LSBiZXN0X21vZCAlPiUNCiAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUgDQogIHB1bGwobW9kZWxfdHlwZSkNCiAgDQp2YXVsZSA8LSBvMmNyaXQkbzJjcml0DQpsb3dlc3RNTzIgPSBxdWFudGlsZShkZl9pJE1PMltkZl9pJERPID49IDgwXSwgcD0wLjA1KQ0KU01SIDwtIG8yY3JpdCRTTVINCm5iX21vMl9jb25mb3JtaW5nIDwtIG8yY3JpdCROYl9NTzJfY29uZm9ybWluZw0KcjIgPC0gbzJjcml0JHIyDQptZXRob2QgPC0gbzJjcml0JE1ldGhvZA0KcCA8LSBvMmNyaXQkUFsxXQ0KbGV0aGFsX3BvaW50IDwtIG1pbihvMmNyaXQkbGV0aGFsUG9pbnRzKQ0KDQpwY3JpdF9tb2RlbF9kZiA8LSB0aWJibGUoDQogICAgICBpZCA9IGlkX2ksDQogICAgICBwY3JpdF92YXVsZSA9IHZhdWxlLA0KICAgICAgcGNyaXRfc21yID0gU01SLA0KICAgICAgcGNyaXRfbG93ZXN0TU8yID0gbG93ZXN0TU8yLA0KICAgICAgcGNyaXRfbmJfbW8yX2NvbmZvcm1pbmcgPSBuYl9tbzJfY29uZm9ybWluZywNCiAgICAgIHBjcml0X2xldGhhbF9wb2ludHMgPSBsZXRoYWxfcG9pbnQsDQogICAgICBwY3JpdF9yMiA9IHIyLA0KICAgICAgcGNyaXRfbWV0aG9kID0gbWV0aG9kLA0KICAgICAgcGNyaXRfcCA9IHAsDQogICAgICBiZXN0X21vZF90eXBlID0gYmVzdF9tb2RfdHlwZQ0KICAgICkNCg0KcGNyaXRfbW9kZWxfZGZfbGlzdFtbaWRfaV1dIDwtIHBjcml0X21vZGVsX2RmDQoNCnBjcml0X21vZGVsc1tbaWRfaV1dIDwtIG8yY3JpdA0KDQp9DQoNCnBjcml0X21vZGVsX2RmIDwtIGJpbmRfcm93cyhwY3JpdF9tb2RlbF9kZl9saXN0KQ0KYGBgDQoNCiMjIyBQbG90aW5nIE8yY3JpdA0KDQpIZXJlJ3Mgd2UgYXJlIHNhdmluZyBhbGwgTzxzdWI+MmNyaXQ8L3N1Yj4gbW9kZWxzLCBldmVuIHRob3NlIE1PPHN1Yj4yPC9zdWI+LU88c3ViPjI8L3N1Yj4gcmVsYXRpb25zaGlwcyBiZXN0IG1vZGVsbGVkIGJ5IDBedGheLSBhbmQgMV5zdF4tb3JkZXIgcG9seW5vbWlhbHMuDQoNCmBgYHtyfQ0KIyBDcmVhdGUgb3V0cHV0IGRpcmVjdG9yeSBpZiBuZWVkZWQNCm91dHB1dF9maWdfcGNyaXRfY2hhYm90X3dkIDwtIGZpbGUucGF0aChvdXRwdXRfZmlnX3dkLCAibW9kZWxfY2hhYm90IikNCmlmICghZGlyLmV4aXN0cyhvdXRwdXRfZmlnX3Bjcml0X2NoYWJvdF93ZCkpIHsNCiAgZGlyLmNyZWF0ZShvdXRwdXRfZmlnX3Bjcml0X2NoYWJvdF93ZCkNCn0NCg0KaWRzIDwtIHNsb3BlX3RpZHkgJT4lDQogIGRwbHlyOjpkaXN0aW5jdChpZCkgJT4lDQogIGRwbHlyOjpwdWxsKCkNCg0KcGNyaXRfY2hhYm90X2xpc3QgPC0gbGlzdCgpDQoNCiMgT3BlbiBhIHNpbmdsZSBQREYgZGV2aWNlDQpwZGYoZmlsZSA9IGZpbGUucGF0aChvdXRwdXRfZmlnX3Bjcml0X2NoYWJvdF93ZCwgImNvbWJpbmVkX2NoYWJvdF9wbG90cy5wZGYiKSwNCiAgICB3aWR0aCA9IDgsIGhlaWdodCA9IDYpDQoNCmZvciAoaWRfaSBpbiBpZHMpIHsNCg0KICBiZXN0X21vZF90eXBlIDwtIGJlc3RfbW9kICU+JQ0KICBkcGx5cjo6ZmlsdGVyKGlkID09IGlkX2kpICU+JQ0KICBwdWxsKG1vZGVsX3R5cGUpDQoNCiAgcjIgPC0gcGNyaXRfbW9kZWxfZGYgJT4lDQogICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUNCiAgICBkcGx5cjo6bXV0YXRlKHBjcml0X3IyID0gcm91bmQocGNyaXRfcjIsIDMpKSAlPiUNCiAgICBkcGx5cjo6cHVsbChwY3JpdF9yMikNCg0KICBjb25mb3JtaW5nIDwtIHBjcml0X21vZGVsX2RmICU+JQ0KICAgIGRwbHlyOjpmaWx0ZXIoaWQgPT0gaWRfaSkgJT4lDQogICAgZHBseXI6Om11dGF0ZShwY3JpdF9uYl9tbzJfY29uZm9ybWluZyA9IHJvdW5kKHBjcml0X25iX21vMl9jb25mb3JtaW5nLCAzKSkgJT4lDQogICAgZHBseXI6OnB1bGwocGNyaXRfbmJfbW8yX2NvbmZvcm1pbmcpDQoNCiAgUCA8LSBwY3JpdF9tb2RlbF9kZiAlPiUNCiAgICBkcGx5cjo6ZmlsdGVyKGlkID09IGlkX2kpICU+JQ0KICAgIGRwbHlyOjptdXRhdGUocGNyaXRfcCA9IHJvdW5kKHBjcml0X3AsIDMpKSAlPiUNCiAgICBkcGx5cjo6cHVsbChwY3JpdF9wKQ0KDQogIFNNUiA8LSBwY3JpdF9tb2RlbF9kZiAlPiUNCiAgICBkcGx5cjo6ZmlsdGVyKGlkID09IGlkX2kpICU+JQ0KICAgIGRwbHlyOjptdXRhdGUocGNyaXRfc21yID0gcm91bmQocGNyaXRfc21yLCAzKSkgJT4lDQogICAgZHBseXI6OnB1bGwocGNyaXRfc21yKQ0KDQogIGxvd2VzdE1PMiA8LSBwY3JpdF9tb2RlbF9kZiAlPiUNCiAgICBkcGx5cjo6ZmlsdGVyKGlkID09IGlkX2kpICU+JQ0KICAgIGRwbHlyOjptdXRhdGUocGNyaXRfbG93ZXN0TU8yID0gcm91bmQocGNyaXRfbG93ZXN0TU8yLCAzKSkgJT4lDQogICAgZHBseXI6OnB1bGwocGNyaXRfbG93ZXN0TU8yKQ0KDQogICMgR2VuZXJhdGUgYW5kIHJlbmRlciB0aGUgcGxvdA0KICBwbG90TzJjcml0KG8yY3JpdG9iaiA9IHBjcml0X21vZGVsc1tbaWRfaV1dKQ0KDQogICMgQWRkIGEgdGl0bGUNCiAgbXRleHQoDQogICAgdGV4dCA9IHBhc3RlMChpZF9pKSwNCiAgICBzaWRlID0gMywgbGluZSA9IDIsIGFkaiA9IDAsDQogICAgY29sID0gImJsdWUiLCBmb250ID0gMiwgY2V4ID0gMS4yDQogICkNCg0KICBtdGV4dCgNCiAgICB0ZXh0ID0gcGFzdGUwKCJSMiA9ICIsIHIyLCAiOyBwID0gIiwgUCwgIjsgQ1AgPCBTTVIgPSAiLCBjb25mb3JtaW5nLCAiOyBTTVIgPSAiLCBTTVIsICI7IGxvd2VzdE1PMiA9ICIsbG93ZXN0TU8yKSwNCiAgICBzaWRlID0gMywgbGluZSA9IDEsIGFkaiA9IDAsDQogICAgY29sID0gImJsdWUiLCBmb250ID0gMSwgY2V4ID0gMC44DQogICkNCg0KICBtdGV4dCgNCiAgICB0ZXh0ID0gcGFzdGUwKCJCZXN0IG1vZGVsIGZpdCA9ICIsIGJlc3RfbW9kX3R5cGUpLA0KICAgIHNpZGUgPSAzLCBsaW5lID0gMCwgYWRqID0gMCwNCiAgICBjb2wgPSAicmVkIiwgZm9udCA9IDEsIGNleCA9IDAuOA0KICApDQp9DQoNCiMgQ2xvc2UgdGhlIFBERiBkZXZpY2UgKmFmdGVyKiB0aGUgbG9vcA0KZGV2Lm9mZigpDQpgYGANCg0KTm93IHByaW50aW5nIHRoZSBmaXNoIHRoYXQgd2VyZSBmaXR0ZWQgd2l0aCBoaWdoZXIgb3JkZXItcG9seW5vbWlhbHMgaW4gdGhlIGh0bG0gZG9jdW1lbnQNCg0KYGBge3IsIGZpZy5oZWlnaHQgPSAzLCBmaWcud2lkdGg9IDh9DQoNCnBhcihtZnJvdyA9IGMoMSwgMiksIG1hciA9IGMoNCwgNCwgNCwgMikpIA0KDQpwY3JpdF9tb2RlbF9tZXRhIDwtIHNsb3BlX3RpZHkgJT4lIA0KICBkcGx5cjo6Z3JvdXBfYnkoaWQpICU+JSANCiAgZHBseXI6OnNsaWNlKDEpICU+JSANCiAgZHBseXI6OnVuZ3JvdXAoKSAlPiUgDQogIGRwbHlyOjpsZWZ0X2pvaW4ocGNyaXRfbW9kZWxfZGYsIC4sIGJ5ID0gImlkIikNCg0KaGlnaGVyX29yZGVyX2lkcyA8LSAgcGNyaXRfbW9kZWxfbWV0YSAlPiUgDQogIGRwbHlyOjpmaWx0ZXIoYmVzdF9tb2RfdHlwZSA9PSAibG1fMiIgfCBiZXN0X21vZF90eXBlID09ICJsbV8zIikgJT4lIA0KICBkcGx5cjo6ZGlzdGluY3QoaWQpICU+JSANCiAgZHBseXI6OnB1bGwoKQ0KDQpmb3IgKGlkX2kgaW4gaGlnaGVyX29yZGVyX2lkcykgew0KICANCiAgDQogIHIyIDwtIHBjcml0X21vZGVsX21ldGEgJT4lIA0KICAgIGRwbHlyOjpmaWx0ZXIoaWQgPT0gaWRfaSkgJT4lIA0KICAgIGRwbHlyOjptdXRhdGUocGNyaXRfcjIgPSByb3VuZChwY3JpdF9yMiwgMykpICU+JSANCiAgICBkcGx5cjo6cHVsbChwY3JpdF9yMikNCiAgDQogIGNvbmZvcm1pbmcgPC0gcGNyaXRfbW9kZWxfbWV0YSAlPiUgDQogICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUgDQogICAgZHBseXI6Om11dGF0ZShwY3JpdF9uYl9tbzJfY29uZm9ybWluZyA9IHJvdW5kKHBjcml0X25iX21vMl9jb25mb3JtaW5nLCAzKSkgJT4lIA0KICAgIGRwbHlyOjpwdWxsKHBjcml0X25iX21vMl9jb25mb3JtaW5nKQ0KICANCiAgUCA8LSBwY3JpdF9tb2RlbF9tZXRhICU+JSANCiAgICBkcGx5cjo6ZmlsdGVyKGlkID09IGlkX2kpICU+JSANCiAgICBkcGx5cjo6bXV0YXRlKHBjcml0X3AgPSByb3VuZChwY3JpdF9wLCAzKSkgJT4lIA0KICAgIGRwbHlyOjpwdWxsKHBjcml0X3ApDQogIA0KICBTTVIgPC0gcGNyaXRfbW9kZWxfbWV0YSAlPiUgDQogICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUgDQogICAgZHBseXI6Om11dGF0ZShwY3JpdF9zbXIgPSByb3VuZChwY3JpdF9zbXIsIDMpKSAlPiUgDQogICAgZHBseXI6OnB1bGwocGNyaXRfc21yKQ0KICANCiAgbG93ZXN0TU8yIDwtIHBjcml0X21vZGVsX21ldGEgJT4lIA0KICAgIGRwbHlyOjpmaWx0ZXIoaWQgPT0gaWRfaSkgJT4lIA0KICAgIGRwbHlyOjptdXRhdGUocGNyaXRfbG93ZXN0TU8yID0gcm91bmQocGNyaXRfbG93ZXN0TU8yLCAzKSkgJT4lIA0KICAgIGRwbHlyOjpwdWxsKHBjcml0X2xvd2VzdE1PMikNCiAgDQogICMgR2VuZXJhdGUgYW5kIHJlbmRlciB0aGUgcGxvdA0KICBwbG90TzJjcml0KG8yY3JpdG9iaiA9IHBjcml0X21vZGVsc1tbaWRfaV1dKQ0KICANCiAgIyBBZGQgYSB0aXRsZQ0KICBtdGV4dCgNCiAgICB0ZXh0ID0gcGFzdGUwKGlkX2kpLA0KICAgIHNpZGUgPSAzLCBsaW5lID0gMiwgYWRqID0gMCwNCiAgICBjb2wgPSAiYmx1ZSIsIGZvbnQgPSAyLCBjZXggPSAxLjINCiAgKQ0KICANCiAgbXRleHQoDQogICAgdGV4dCA9IHBhc3RlMCgiUjIgPSAiLCByMiwgIjsgcCA9ICIsIFAsICI7IENQIDwgU01SID0gIiwgY29uZm9ybWluZyksDQogICAgc2lkZSA9IDMsIGxpbmUgPSAxLCBhZGogPSAwLA0KICAgIGNvbCA9ICJibHVlIiwgZm9udCA9IDAuNSwgY2V4ID0gMC44DQogICkNCiAgDQogICBtdGV4dCgNCiAgICB0ZXh0ID0gcGFzdGUwKCJTTVIgPSAiLCBTTVIsICI7IGxvd2VzdE1PMiA9ICIsbG93ZXN0TU8yKSwNCiAgICBzaWRlID0gMywgbGluZSA9IDAsIGFkaiA9IDAsDQogICAgY29sID0gImJsdWUiLCBmb250ID0gMC41LCBjZXggPSAwLjgNCiAgKQ0KfQ0KYGBgDQoNCg0KIyMjIE/igoJjcml0IG51bWVyaWNhbCBydWxlcw0KDQpXZSBhcHBsaWVkIGEgbnVtZXJpY2FsIHJ1bGUgdG8gYXNzZXMgaWYgYSBPPHN1Yj4yY3JpdDwvc3ViPiB3YXMgb2JzZXJ2ZWQuIFNwZWNpZmljYWxseSwgd2UgZmlsdGVyZWQgZm9yIG9ubHkgY2FzZXMgd2VyZSBhdCB0aGUgbG93ZXN0IE/igoIgdmFsdWUgdGhyZWUgY29uc2VjdXRpdmUgTU/igoIgbWVhc3VyZXMgZnVsbCBiZWxvdyBvdXIgU01SIGFuZCBmaWZ0aCBwZXJjZW50aWxlIG9mIHRoZSBNTzIgdmFsdWVzIG9ic2VydmVkIGF0IGRpc3NvbHZlZCBPMiBsZXZlbHMgPiA4MCUuIEluIHRoZSBtb2RlbCBvdXRwdXQgdGhlc2UgYXJlIGNhbGxlZCBuYl9tbzJfY29uZm9ybWluZyBwb2ludHMuDQoNCmBgYHtyfQ0KbzJjcml0X251bWVyaWNhbF95ZXMgPC0gcGNyaXRfbW9kZWxfZGYgJT4lIA0KICBkcGx5cjo6ZmlsdGVyKHBjcml0X25iX21vMl9jb25mb3JtaW5nID4gMikgJT4lIA0KICBwdWxsKGlkKQ0KDQpwYXN0ZTAoIkJhc2VkIG9uIHRoaXMgcnVsZSB0aGVyZSBhcmUgIiwgbGVuZ3RoKG8yY3JpdF9udW1lcmljYWxfeWVzKSwgIiBmaXNoIHdpdGggcG9zc2libGUgT+KCgmNyaXRzLiIpDQpgYGANCg0KDQojIyMjIEZpZ3VyZSBTNg0KDQpQbG90dGluZyBmaXNoIHRoYXQgbWVldCBvdXIgbnVtZXJpY2FsIHJ1bGUgZm9yIE88c3ViPjJjcml0PC9zdWI+IA0KDQpgYGB7ciwgZmlnLmhlaWdodCA9IDMsIGZpZy53aWR0aD0gOH0NCg0KcGFyKG1mcm93ID0gYygxLCAyKSwgbWFyID0gYyg0LCA0LCA0LCAyKSkgDQoNCmZvciAoaWRfaSBpbiBvMmNyaXRfbnVtZXJpY2FsX3llcykgew0KICANCiAgDQogIHIyIDwtIHBjcml0X21vZGVsX21ldGEgJT4lIA0KICAgIGRwbHlyOjpmaWx0ZXIoaWQgPT0gaWRfaSkgJT4lIA0KICAgIGRwbHlyOjptdXRhdGUocGNyaXRfcjIgPSByb3VuZChwY3JpdF9yMiwgMykpICU+JSANCiAgICBkcGx5cjo6cHVsbChwY3JpdF9yMikNCiAgDQogIGNvbmZvcm1pbmcgPC0gcGNyaXRfbW9kZWxfbWV0YSAlPiUgDQogICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUgDQogICAgZHBseXI6Om11dGF0ZShwY3JpdF9uYl9tbzJfY29uZm9ybWluZyA9IHJvdW5kKHBjcml0X25iX21vMl9jb25mb3JtaW5nLCAzKSkgJT4lIA0KICAgIGRwbHlyOjpwdWxsKHBjcml0X25iX21vMl9jb25mb3JtaW5nKQ0KICANCiAgUCA8LSBwY3JpdF9tb2RlbF9tZXRhICU+JSANCiAgICBkcGx5cjo6ZmlsdGVyKGlkID09IGlkX2kpICU+JSANCiAgICBkcGx5cjo6bXV0YXRlKHBjcml0X3AgPSByb3VuZChwY3JpdF9wLCAzKSkgJT4lIA0KICAgIGRwbHlyOjpwdWxsKHBjcml0X3ApDQogIA0KICBTTVIgPC0gcGNyaXRfbW9kZWxfbWV0YSAlPiUgDQogICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUgDQogICAgZHBseXI6Om11dGF0ZShwY3JpdF9zbXIgPSByb3VuZChwY3JpdF9zbXIsIDMpKSAlPiUgDQogICAgZHBseXI6OnB1bGwocGNyaXRfc21yKQ0KICANCiAgbG93ZXN0TU8yIDwtIHBjcml0X21vZGVsX21ldGEgJT4lIA0KICAgIGRwbHlyOjpmaWx0ZXIoaWQgPT0gaWRfaSkgJT4lIA0KICAgIGRwbHlyOjptdXRhdGUocGNyaXRfbG93ZXN0TU8yID0gcm91bmQocGNyaXRfbG93ZXN0TU8yLCAzKSkgJT4lIA0KICAgIGRwbHlyOjpwdWxsKHBjcml0X2xvd2VzdE1PMikNCiAgDQogICMgR2VuZXJhdGUgYW5kIHJlbmRlciB0aGUgcGxvdA0KICBwbG90TzJjcml0KG8yY3JpdG9iaiA9IHBjcml0X21vZGVsc1tbaWRfaV1dKQ0KICANCiAgIyBBZGQgYSB0aXRsZQ0KICBtdGV4dCgNCiAgICB0ZXh0ID0gcGFzdGUwKGlkX2kpLA0KICAgIHNpZGUgPSAzLCBsaW5lID0gMiwgYWRqID0gMCwNCiAgICBjb2wgPSAiYmx1ZSIsIGZvbnQgPSAyLCBjZXggPSAxLjINCiAgKQ0KICANCiAgbXRleHQoDQogICAgdGV4dCA9IHBhc3RlMCgiUjIgPSAiLCByMiwgIjsgcCA9ICIsIFAsICI7IENQIDwgU01SID0gIiwgY29uZm9ybWluZyksDQogICAgc2lkZSA9IDMsIGxpbmUgPSAxLCBhZGogPSAwLA0KICAgIGNvbCA9ICJibHVlIiwgZm9udCA9IDAuNSwgY2V4ID0gMC44DQogICkNCiAgDQogICBtdGV4dCgNCiAgICB0ZXh0ID0gcGFzdGUwKCJTTVIgPSAiLCBTTVIsICI7IGxvd2VzdE1PMiA9ICIsbG93ZXN0TU8yKSwNCiAgICBzaWRlID0gMywgbGluZSA9IDAsIGFkaiA9IDAsDQogICAgY29sID0gImJsdWUiLCBmb250ID0gMC41LCBjZXggPSAwLjgNCiAgKQ0KfQ0KYGBgDQoNCioqRmlndXJlIFM2Kio6IFJlcHJlc2VudGF0aXZlIGV4YW1wbGVzIG9mIGZpc2ggdGhhdCB3ZXJlIGJlc3QgbW9kZWxsZWQgYnkgYSAybmQtIG9yIDNyZC1vcmRlciBwb2x5bm9taWFsIGFuZCBtZWV0IHRoZSBudW1lcmljYWwgaW5jbHVzaW9uIGNyaXRlcmlhLiBUaGUgaG9yaXpvbnRhbCBzb2xpZCBvcmFuZ2UgbGluZSBzaG93cyB0aGUgc3RhbmRhcmQgbWV0YWJvbGljIHJhdGUgKFNNUiksIHRoZSBob3Jpem9udGFsIHNvbGlkIHBpbmsgbGluZSBzaG93cyB0aGVsb3dlc3RNTzIgKGFzIGRlZmluZWQgYnkgIENsYWlyZWF1eCBhbmQgQ2hhYm90ICgyMDE2KSksIHRoZSBzb2xpZC9kYXNoZWQgYmx1ZS9ncmVlbiBzbG9wZSBsaW5lIHNob3dzIHRoZSBPMiByZWd1bGF0aW9uIGZhaWx1cmUgcmVncmVzc2lvbiAoYmFzZWQgb24gdGhlIHJ1bGUtYmFzZWQgbGluZWFyIHJlZ3Jlc3Npb24gbWV0aG9kIG9mIENsYWlyZWF1eCBhbmQgQ2hhYm90ICgyMDE2KTsgd2hlcmUgdGhlIGNvbG91ciBhbmQgbGluZSB0eXBlIGluZGljYXRlIHRoZSB0eXBlIG9mIHJlZ3Jlc3Npb24gZml0dGVkLCB0aHJvdWdoIG9yZ2luIG9yIG5vdCksIGFuZCB0aGUgc29saWQgdmVydGljYWwgYmx1ZS9ncmVlbiBsaW5lIHNob3dzIHRoZSBPMmNyaXQgZXN0aW1hdGUgKGludGVyc2VjdGlvbiBvZiBPMiBmYWlsdXJlIHJlZ3Jlc3Npb24gYW5kIFNNUikuDQoNCkhvdyBtYW55IGZyb20gZWFjaCBzYWxpbml0eSB0cmVhdG1lbnQNCg0KYGBge3J9DQpzbG9wZV90aWR5ICU+JSANCiAgZHBseXI6OmZpbHRlcihpZCAlaW4lIG8yY3JpdF9udW1lcmljYWxfeWVzKSAlPiUgDQogIGRwbHlyOjpncm91cF9ieShpZCkgJT4lIA0KICBkcGx5cjo6c2xpY2UoMSkgJT4lIA0KICBkcGx5cjo6dW5ncm91cCgpICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KHNhbGluaXR5X2dyb3VwKSAlPiUgDQogIGRwbHlyOjpyZWZyYW1lKG4gPSBsZW5ndGggKGlkKSkgJT4lIA0KICBkcGx5cjo6dW5ncm91cCgpICU+JSANCiAgZ3QoKQ0KYGBgDQoNCiMjIyBWaXN1YWwgaW5zcGVjdGlvbg0KDQpXZSBjb25kdWN0ZWQgdmlzdWFsIGluc3BlY3Rpb24gb2YgYWxsIDU4IGZpc2ggdG8gZGV0ZXJtaW5lIGlmIE88c3ViPjJjcml0czwvc3ViPiB3ZXJlIHByZXNlbnQuIFdlIGhhdmUgbG9hZGVkIHRoaXMgYXMgYSBkYXRhIGZyYW1lICoq8J+SvyBvMmNyaXRfY2hlY2sqKg0KDQpGb3IgdGhpcyB2aXN1YWwgaW5zcGVjdGlvbiwgd2UgZ3JvdXBlZCBmaXNoIGludG8gIm5vIiwgIm1heWJlIiBvciAieWVzIiwgYmFzZWQgb24gdGhlIGNlcnRhaW50eSBhdCB3aGljaCB3ZSBvYnNlcnZlZCBhIE88c3ViPjJjcml0czwvc3ViPi4gSW4gdGhlIGNhc2Ugb2YgeWVzIG9yIG1heWJlLCB3ZSBhbHNvIGVzdGltYXRlIGRpc3NvbHZlZCBveHlnZW4gcGVyY2VudGFnZS4gQWxsIGF1dGhvcnMgZGlkIHRoaXMgaW5kZXBlbmRlbnRseS4gIA0KDQojIyMjIPCfk4ggUmVzdWx0cw0KDQpMZXQncyBmaWd1cmUgb3V0IGhvdyBjb25zaXN0ZW50IHRoZSBjYXRlZ29yaXNhdGlvbiB3YXMsIGFuZCB3aGF0IHRoZSBtYWpvcml0eSByZXNwb25zZSB3YXMuIFRoZXJlIHdlcmUgMzUgY2FzZXMgd2l0aCBubyBkaXNhZ3JlZW1lbnRzICg2MC4zNCUpLCAyMyBjYXNlcyB3aXRoIG9uZSBvciBtb3JlIGRpc2FncmVlbWVudHMgKDM5LjY2JSkuICANCg0KYGBge3J9DQpkaXNhZ3JlZW1lbnRfc3VtbWFyeSA8LSBvMmNyaXRfY2hlY2sgJT4lDQogIGdyb3VwX2J5KGlkKSAlPiUNCiAgZHBseXI6OnJlZnJhbWUoDQogICAgbl9kaXNhZ3JlZW1lbnQgPSBuX2Rpc3RpbmN0KHBjcml0X2NhdCktMSwNCiAgICBjYXRfZGlzYWdyZWVtZW50ID0gaWZfZWxzZShuX2Rpc2FncmVlbWVudD09MCwgMCwgMSksDQogICAgbWFqb3JpdHlfY2F0ID0gbmFtZXMoc29ydCh0YWJsZShwY3JpdF9jYXQpLCBkZWNyZWFzaW5nID0gVFJVRSkpWzFdLA0KICAgIGNlcnRhaW50eSA9IG1heCh0YWJsZShwY3JpdF9jYXQpLzUqMTAwKQ0KICApDQoNCnRvdGFsX2Fzc2VzbWVudCA8LSBvMmNyaXRfY2hlY2sgJT4lIA0KICBkaXN0aW5jdChpZCkgJT4lIA0KICBucm93KCkNCg0KZGlzYWdyZWVtZW50X3N1bW1hcnkgJT4lDQogIGdyb3VwX2J5KGNhdF9kaXNhZ3JlZW1lbnQpICU+JSANCiAgZHBseXI6OnJlZnJhbWUoDQogICAgbiA9IGxlbmd0aChpZCksDQogICAgcGVyY2VudCA9IHJvdW5kKG4vdG90YWxfYXNzZXNtZW50KjEwMCwyKQ0KICApICU+JSANCiAgZ3QoKQ0KYGBgDQoNCiMjIyMgRmlndXJlIFM3DQoNCkhlcmUncyBhIGhlYXQgbWFwIHRvIHNob3cgZGVjaXNpb25zIGZvciBlYWNoIGZpc2gNCg0KYGBge3IsIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD01fQ0KIyBEZWZpbmUgY3VzdG9tIGNvbG91cnMgZm9yIHBjcml0X2NhdA0KY2F0ZWdvcnlfY29sb3VycyA8LSBjKA0KICAibm8iID0gIiNFMDNDMzIiLA0KICAibWF5YmUiID0gIiNGRkQzMDEiLA0KICAieWVzIiA9ICIjN0JCNjYyIg0KKQ0KDQojIENyZWF0ZSBoZWF0bWFwDQpnZ3Bsb3QobzJjcml0X2NoZWNrLCBhZXMoeCA9IGV4cGVydCwgeSA9IGlkLCBmaWxsID0gcGNyaXRfY2F0KSkgKw0KICBnZW9tX3RpbGUoY29sb3VyID0gIndoaXRlIikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjYXRlZ29yeV9jb2xvdXJzLCBuYS52YWx1ZSA9ICJncmV5OTAiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiVmlzdWFsIEFzc2Vzc21lbnQgb2YgcGNyaXRfY2F0IGJ5IEV4cGVydCBhbmQgSUQiLA0KICAgIHggPSAiRXhwZXJ0IiwNCiAgICB5ID0gIkZpc2ggSUQiLA0KICAgIGZpbGwgPSAiQ2F0ZWdvcnkiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gNyksICMgYWRqdXN0IHNpemUgYXMgbmVlZGVkDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwNCiAgICBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpDQogICkNCmBgYA0KDQoNCioqRmlndXJlIFM3Kio6IEhlYXRtYXAgc2hvd2luZyB0aGUgdmlzdWFsIGFzc2Vzc21lbnQgb2YgY3JpdGljYWwgb3h5Z2VuIHNhdHVyYXRpb24gKE88c3ViPjJjcml0czwvc3ViPikgY2F0ZWdvcnkgKCJubyIsICJtYXliZSIgb3IgInllcyIpIGZvciBlYWNoIGZpc2ggYnkgZXhwZXJ0IGFzc2Vzc29yIChFbGl6YWJldGggQy4gSG9vdHMgW2VjaF0sIEpha2UgTS4gTWFydGluIFtqbW1dLCBMdWlzIEwuIEt1Y2hlbm3DvGxsZSBbbGxrXSBNYXJ5YW5lIEdyYWRpdG8gW21nXSwgVGltb3RoeSBELiBDbGFyayBbdGRjXSkuIEVhY2ggdGlsZSByZXByZXNlbnRzIG9uZSBmaXNoLWV4cGVydCBwYWlyaW5nLCBjb2xvdXItY29kZWQgYnkgYXNzaWduZWQgY2F0ZWdvcnk6DQo8c3BhbiBzdHlsZT0iY29sb3I6I0UwM0MzMiI+PHN0cm9uZz5ubzwvc3Ryb25nPjwvc3Bhbj4gKHJlZCwgI0UwM0MzMiksDQo8c3BhbiBzdHlsZT0iY29sb3I6I0ZGRDMwMSI+PHN0cm9uZz5tYXliZTwvc3Ryb25nPjwvc3Bhbj4gKHllbGxvdywgI0ZGRDMwMSksIGFuZA0KPHNwYW4gc3R5bGU9ImNvbG9yOiM3QkI2NjIiPjxzdHJvbmc+eWVzPC9zdHJvbmc+PC9zcGFuPiAoZ3JlZW4sICM3QkI2NjIpLg0KDQpFeHBlcnQgZGV2aWF0aW9uIGZyb20gdGhlIG1ham9yaXR5IGFzc2Vzc21lbnQgcmFuZ2VkIGZyb20gMjIuNDEgdG8gNi45MCUuDQoNCmBgYHtyfQ0KbzJjcml0X2NoZWNrX3N1bSA8LSBvMmNyaXRfY2hlY2sgJT4lIA0KICBkcGx5cjo6bGVmdF9qb2luKC4sIGRpc2FncmVlbWVudF9zdW1tYXJ5LCBieSA9ICJpZCIpICU+JSANCiAgZHBseXI6Om11dGF0ZShkZXZpYXRlZCA9IGlmX2Vsc2UocGNyaXRfY2F0ICE9IG1ham9yaXR5X2NhdCwgMSwgMCkpDQoNCm8yY3JpdF9jaGVja19zdW0gJT4lDQogIGdyb3VwX2J5KGV4cGVydCkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBkZXZpYXRpb25zID0gc3VtKGRldmlhdGVkKSwNCiAgICBkZXZpYXRpb25fcmF0ZSA9IHJvdW5kKGRldmlhdGlvbnMgLyA1OCAqIDEwMCwgMikNCiAgKSAlPiUgDQogIGRwbHlyOjphcnJhbmdlKGRlc2MoZGV2aWF0aW9ucykpICU+JSANCiAgZ3QoKQ0KYGBgDQoNCkxldCdzIG1ha2UgYSBsaXN0IG9mIHRob3NlIHRoYXQgaGFkIG1ham9yaXR5IGFzc2lnbmVkIGFzIHllcyBmb3IgYW4gTzxzdWI+MmNyaXQ8L3N1Yj4uIFRoZXJlIHdhcyAxMCB0b3RhbC4gIA0KDQpgYGB7cn0NCm8yY3JpdF92aXN1YWxfeWVzIDwtICBkaXNhZ3JlZW1lbnRfc3VtbWFyeSAlPiUgDQogIGRwbHlyOjpmaWx0ZXIobWFqb3JpdHlfY2F0ID09ICJ5ZXMiKSAlPiUgDQogIGRwbHlyOjpwdWxsKGlkKQ0KDQpwYXN0ZTAoIkJhc2VkIG9uIHRoZSBtYWpvcml0eSB2aXN1YWwgYXNzZXNzbWVudCAiLCBsZW5ndGgobzJjcml0X3Zpc3VhbF95ZXMpLCAiIGZpc2ggaGF2ZSBwb3NzaWJsZSBP4oKCY3JpdC4iKQ0KYGBgDQoNCiMjIyBP4oKCY3JpdCBudW1iZXJzDQoNCldlIHdpbGwgbm93IGNoZWNrIHRvIHNlZSB3aGljaCBmaXNoIGhhdmUgTzxzdWI+MmNyaXQ8L3N1Yj4gYmFzZWQgb24gdGhlIG51bWVyaWNhbCBhbmQgdmlzdWFsIGluc3BlY3Rpb25zLiAgIA0KDQpUaGVyZSBhcmUgZWlnaHQgZmlzaCB0aGF0IGJvdGggbnVtZXJpY2FsbHkgYW5kIHZpc3VhbGx5IHdlcmUgZGV0ZXJtaW5lZCB0byBoYXZlIGEgTzxzdWI+MmNyaXQ8L3N1Yj4uIFR3byBmaXNoIHdpdGggYSB2aXN1YWxseSBjb25maXJtZWQgTzxzdWI+MmNyaXQ8L3N1Yj4sIHRoYXQgZGlkIG5vdCBtZWV0IHRoZSBudW1lcmljYWwgY3JpdGVyaWEuIEVpZ2h0IGZpc2ggbWVldCB0aGUgbnVtZXJpY2FsIGNyaXRlcmlhLCBidXQgZGlkIG5vdCBwYXNzIHRoZSB2aXN1YWwgaW5zcGVjdGlvbi4gIA0KDQpgYGB7cn0NCnNoYXJlZF9lbGVtZW50cyA8LSBpbnRlcnNlY3QobzJjcml0X3Zpc3VhbF95ZXMsIG8yY3JpdF9udW1lcmljYWxfeWVzKQ0KDQp1bmlxdWVfdG9fdmlzdWFsIDwtIHNldGRpZmYobzJjcml0X3Zpc3VhbF95ZXMsIG8yY3JpdF9udW1lcmljYWxfeWVzKQ0KDQp1bmlxdWVfdG9fbnVtZXJpY2FsIDwtIHNldGRpZmYobzJjcml0X251bWVyaWNhbF95ZXMsIG8yY3JpdF92aXN1YWxfeWVzKQ0KDQpsaXN0KA0KICBTaGFyZWQgPSBzaGFyZWRfZWxlbWVudHMsDQogIFVuaXF1ZV90b192aXN1YWwgPSB1bmlxdWVfdG9fdmlzdWFsLA0KICBVbmlxdWVfdG9fbnVtZXJpY2FsID0gdW5pcXVlX3RvX251bWVyaWNhbA0KKQ0KYGBgDQoNCkhvdyBtYW55IHBlciBzYWxpbml0eSB0cmVhdG1lbnQgDQoNCmBgYHtyfQ0Kc2xvcGVfdGlkeSAlPiUgDQogIGRwbHlyOjpmaWx0ZXIoaWQgJWluJSBzaGFyZWRfZWxlbWVudHMpICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KGlkKSAlPiUgDQogIGRwbHlyOjpzbGljZSgxKSAlPiUgDQogIGRwbHlyOjp1bmdyb3VwKCkgJT4lIA0KICBkcGx5cjo6Z3JvdXBfYnkoc2FsaW5pdHlfZ3JvdXApICU+JSANCiAgZHBseXI6OnJlZnJhbWUobiA9IGxlbmd0aCAoaWQpKSAlPiUgDQogIGRwbHlyOjp1bmdyb3VwKCkgJT4lIA0KICBndCgpDQpgYGANCg0KDQojIyMjIPCfk4ggUmVzdWx0cw0KDQpMb29raW5nIGF0IG1lYW4gTzxzdWI+MmNyaXQ8L3N1Yj4gZXN0aW1hdGVzLiAgIA0KDQpgYGB7cn0NCnBvcF9tYXNzIDwtIHBjcml0X21vZGVsX21ldGEgJT4lIA0KICBkcGx5cjo6cmVmcmFtZSgNCiAgICBtZWFuX21hc3MgPSBtZWFuKG1hc3MpDQogICkgJT4lIA0KICBwdWxsKG1lYW5fbWFzcykNCg0KcGNyaXRfbW9kZWxfbWV0YSAlPiUgDQogIGRwbHlyOjpmaWx0ZXIoaWQgJWluJSBzaGFyZWRfZWxlbWVudHMpICU+JSANCiAgZHBseXI6Om11dGF0ZShyZWxfbWFzcyA9IG1hc3MvcG9wX21hc3MpICU+JSANCiAgZHBseXI6OnJlZnJhbWUoDQogICAgbl9vMmNyaXQgPSBsZW5ndGgocGNyaXRfdmF1bGUpLA0KICAgIG1lYW5fbzJjcml0ID0gbWVhbihwY3JpdF92YXVsZSksDQogICAgbWluX28yY3JpdCA9IG1pbihwY3JpdF92YXVsZSksDQogICAgbWF4X28yY3JpdCA9IG1heChwY3JpdF92YXVsZSksDQogICAgbWVhbl9tYXNzID0gbWVhbihtYXNzKSwNCiAgICBtZWFuX3JlbF9tYXNzID0gbWVhbiAocmVsX21hc3MpLA0KICAgIHNkX21hc3MgPSBzZChtYXNzKSwNCiAgICBzZF9yZWxfbWFzcyA9IHNkKHJlbF9tYXNzKQ0KICApICU+JSANCiAgZ3QoKSAlPiUgDQogICAgZm10X251bWJlcigNCiAgICBjb2x1bW5zID0gd2hlcmUoaXMubnVtZXJpYyksDQogICAgZGVjaW1hbHMgPSAyDQogICkNCmBgYA0KDQoNCmBgYHtyfQ0KbWluX2RvcyA8LSBzbG9wZV90aWR5ICU+JSANCiAgZHBseXI6OmZpbHRlcighKGlkICVpbiUgc2hhcmVkX2VsZW1lbnRzKSkgJT4lDQogIGdyb3VwX2J5KGlkKSAlPiUgDQogIGRwbHlyOjpyZWZyYW1lKA0KICAgIG1pbl9kbyA9IG1pbihETykNCiAgKQ0KDQptaW5fZG9zICU+JSANCiAgZHBseXI6OnJlZnJhbWUoDQogICAgbWVhbl9taW5fZG8gPSByb3VuZChtZWFuKG1pbl9kbyksMiksDQogICAgc2RfbWluX2RvID0gcm91bmQoc2QobWluX2RvKSwyKSwNCiAgICBtaW5fbWluX2RvID0gcm91bmQobWluKG1pbl9kbyksMikNCiAgKSAlPiUgDQogIGd0KCkNCmBgYA0KDQoNCg0KDQpgYGB7cn0NCnBjcml0X21vZGVsX21ldGEgJT4lIA0KICBkcGx5cjo6ZmlsdGVyKGlkICVpbiUgc2hhcmVkX2VsZW1lbnRzKSAlPiUgDQogIGRwbHlyOjpncm91cF9ieShzYWxpbml0eV9ncm91cCkgJT4lIA0KICBkcGx5cjo6cmVmcmFtZSgNCiAgICBuX28yY3JpdCA9IGxlbmd0aChwY3JpdF92YXVsZSksDQogICAgbWVhbl9vMmNyaXQgPSBtZWFuKHBjcml0X3ZhdWxlKSwNCiAgICBtaW5fbzJjcml0ID0gbWluKHBjcml0X3ZhdWxlKSwNCiAgICBtYXhfbzJjcml0ID0gbWF4KHBjcml0X3ZhdWxlKSwNCiAgICBtZWFuX21hc3MgPSBtZWFuKG1hc3MpDQogICkgJT4lIA0KICBndCgpDQpgYGANCg0KIyMjIEZpZ3VyZSBTOA0KDQpUaGVzZSBhcmUgdGhlIDggZmlzaCB0aGF0IG1lZXQgbnVtZXJpY2FsIGNyaXRlcmlhIGFuZCBwYXNzZWQgdmlzdWFsIGluc3BlY3Rpb24uDQoNCmBgYHtyLCBmaWcuaGVpZ2h0ID0gMywgZmlnLndpZHRoPSA4fQ0KDQpwYXIobWZyb3cgPSBjKDEsIDIpLCBtYXIgPSBjKDQsIDQsIDQsIDIpKSANCg0KZm9yIChpZF9pIGluIHNoYXJlZF9lbGVtZW50cykgew0KICANCiAgY29tbWVudCA8LSBwY3JpdF9tb2RlbF9tZXRhICU+JSANCiAgICBkcGx5cjo6ZmlsdGVyKGlkID09IGlkX2kpICU+JSANCiAgICBkcGx5cjo6c2xpY2UoMSkgJT4lIA0KICAgIGRwbHlyOjptdXRhdGUoY29tbWVudCA9IGlmX2Vsc2UoaXMubmEoY29tbWVudHMpLCAiIiwgcGFzdGUwKCIjIiwgY29tbWVudHMpKSkgJT4lIA0KICAgIHB1bGwoY29tbWVudCkNCiAgDQogIHIyIDwtIHBjcml0X21vZGVsX21ldGEgJT4lIA0KICAgIGRwbHlyOjpmaWx0ZXIoaWQgPT0gaWRfaSkgJT4lIA0KICAgIGRwbHlyOjptdXRhdGUocGNyaXRfcjIgPSByb3VuZChwY3JpdF9yMiwgMykpICU+JSANCiAgICBkcGx5cjo6cHVsbChwY3JpdF9yMikNCiAgDQogIGNvbmZvcm1pbmcgPC0gcGNyaXRfbW9kZWxfbWV0YSAlPiUgDQogICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUgDQogICAgZHBseXI6Om11dGF0ZShwY3JpdF9uYl9tbzJfY29uZm9ybWluZyA9IHJvdW5kKHBjcml0X25iX21vMl9jb25mb3JtaW5nLCAzKSkgJT4lIA0KICAgIGRwbHlyOjpwdWxsKHBjcml0X25iX21vMl9jb25mb3JtaW5nKQ0KICANCiAgUCA8LSBwY3JpdF9tb2RlbF9tZXRhICU+JSANCiAgICBkcGx5cjo6ZmlsdGVyKGlkID09IGlkX2kpICU+JSANCiAgICBkcGx5cjo6bXV0YXRlKHBjcml0X3AgPSByb3VuZChwY3JpdF9wLCAzKSkgJT4lIA0KICAgIGRwbHlyOjpwdWxsKHBjcml0X3ApDQogIA0KICBTTVIgPC0gcGNyaXRfbW9kZWxfbWV0YSAlPiUgDQogICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUgDQogICAgZHBseXI6Om11dGF0ZShwY3JpdF9zbXIgPSByb3VuZChwY3JpdF9zbXIsIDMpKSAlPiUgDQogICAgZHBseXI6OnB1bGwocGNyaXRfc21yKQ0KICANCiAgbG93ZXN0TU8yIDwtIHBjcml0X21vZGVsX21ldGEgJT4lIA0KICAgIGRwbHlyOjpmaWx0ZXIoaWQgPT0gaWRfaSkgJT4lIA0KICAgIGRwbHlyOjptdXRhdGUocGNyaXRfbG93ZXN0TU8yID0gcm91bmQocGNyaXRfbG93ZXN0TU8yLCAzKSkgJT4lIA0KICAgIGRwbHlyOjpwdWxsKHBjcml0X2xvd2VzdE1PMikNCiAgDQogICMgR2VuZXJhdGUgYW5kIHJlbmRlciB0aGUgcGxvdA0KICBwbG90TzJjcml0KG8yY3JpdG9iaiA9IHBjcml0X21vZGVsc1tbaWRfaV1dKQ0KICANCiAgIyBBZGQgYSB0aXRsZQ0KICBtdGV4dCgNCiAgICB0ZXh0ID0gcGFzdGUwKGlkX2ksICIgIiwgY29tbWVudCksDQogICAgc2lkZSA9IDMsIGxpbmUgPSAyLCBhZGogPSAwLA0KICAgIGNvbCA9ICJibHVlIiwgZm9udCA9IDIsIGNleCA9IDEuMg0KICApDQogIA0KICBtdGV4dCgNCiAgICB0ZXh0ID0gcGFzdGUwKCJSMiA9ICIsIHIyLCAiOyBwID0gIiwgUCwgIjsgQ1AgPCBTTVIgPSAiLCBjb25mb3JtaW5nLCAiOyBTTVIgPSAiLCBTTVIsICI7IGxvd2VzdE1PMiA9ICIsbG93ZXN0TU8yKSwNCiAgICBzaWRlID0gMywgbGluZSA9IDEsIGFkaiA9IDAsDQogICAgY29sID0gImJsdWUiLCBmb250ID0gMSwgY2V4ID0gMC44DQogICkNCn0NCmBgYA0KDQoqKkZpZ3VyZSBTOCoqOiBSZXByZXNlbnRhdGl2ZSBleGFtcGxlcyBvZiBmaXNoIHRoYXQgd2VyZSBiZXN0IG1vZGVsbGVkIGJ5IGEgMm5kLSBvciAzcmQtb3JkZXIgcG9seW5vbWlhbCBhbmQgbWVldCB0aGUgbnVtZXJpY2FsIGluY2x1c2lvbiBjcml0ZXJpYS4gVGhlIGhvcml6b250YWwgc29saWQgb3JhbmdlIGxpbmUgc2hvd3MgdGhlIHN0YW5kYXJkIG1ldGFib2xpYyByYXRlIChTTVIpLCB0aGUgaG9yaXpvbnRhbCBzb2xpZCBwaW5rIGxpbmUgc2hvd3MgdGhlbG93ZXN0TU8yIChhcyBkZWZpbmVkIGJ5ICBDbGFpcmVhdXggYW5kIENoYWJvdCAoMjAxNikpLCB0aGUgc29saWQvZGFzaGVkIGJsdWUvZ3JlZW4gc2xvcGUgbGluZSBzaG93cyB0aGUgTzIgcmVndWxhdGlvbiBmYWlsdXJlIHJlZ3Jlc3Npb24gKGJhc2VkIG9uIHRoZSBydWxlLWJhc2VkIGxpbmVhciByZWdyZXNzaW9uIG1ldGhvZCBvZiBDbGFpcmVhdXggYW5kIENoYWJvdCAoMjAxNik7IHdoZXJlIHRoZSBjb2xvdXIgYW5kIGxpbmUgdHlwZSBpbmRpY2F0ZSB0aGUgdHlwZSBvZiByZWdyZXNzaW9uIGZpdHRlZCwgdGhyb3VnaCBvcmdpbiBvciBub3QpLCBhbmQgdGhlIHNvbGlkIHZlcnRpY2FsIGJsdWUvZ3JlZW4gbGluZSBzaG93cyB0aGUgTzJjcml0IGVzdGltYXRlIChpbnRlcnNlY3Rpb24gb2YgTzIgZmFpbHVyZSByZWdyZXNzaW9uIGFuZCBTTVIpLg0KDQpQdWxsaW5nIG1vZGVsIG1ldGhvZCBhbmQgbGV0aGFsIHBvaW50cw0KDQpgYGB7cn0NCmlkcyA8LSBwY3JpdF9tb2RlbF9tZXRhICU+JSANCiAgZHBseXI6OmRpc3RpbmN0KGlkKSAlPiUgDQogIGRwbHlyOjpwdWxsKCkNCg0KcGNyaXRfbWVhbl9wbG90IDwtIGxpc3QoKQ0KDQpmb3IgKGlkX2kgaW4gaWRzKSB7DQogIGJlc3RfbW9kX3R5cGUgPC0gYmVzdF9tb2QgJT4lDQogICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUgDQogICAgcHVsbChtb2RlbF90eXBlKQ0KICBtb2QgPC0gcGNyaXRfbW9kZWxzW1tpZF9pXV0NCiAgZGF0YSA8LSBtb2Qkb3JpZ0RhdGENCiAgbWluX2xlYXRoYWwgPC0gbWluKG1vZCRsZXRoYWxQb2ludHMpDQogIG1ldGhvZCA8LSBtb2QkTWV0aG9kDQogIHBjcml0IDwtIG1vZCRvMmNyaXQNCiAgZGF0YV9zbG9wZSA8LSBkYXRhICU+JQ0KICAgIGRwbHlyOjptdXRhdGUobl9yb3cgPSAxOm5yb3coLiksDQogICAgICAgICAgICAgICAgICBsZWF0aGFsID0gaWZfZWxzZShuX3JvdyA+PSBtaW5fbGVhdGhhbCwgIm5vbnJlZ3VsYXRpb24iLCAicmVndWxhdGlvbiIpLA0KICAgICAgICAgICAgICAgICAgbWV0aG9kID0gbWV0aG9kLA0KICAgICAgICAgICAgICAgICAgcGNyaXQgPSBwY3JpdCwNCiAgICAgICAgICAgICAgICAgIGJlc3RfbW9kX3R5cGUgPSBiZXN0X21vZF90eXBlDQogICAgKQ0KICBwY3JpdF9tZWFuX3Bsb3RbW2lkX2ldXSA8LSBkYXRhX3Nsb3BlDQp9DQoNCnBjcml0X21lYW5fcGxvdF9kZiA8LSBiaW5kX3Jvd3MocGNyaXRfbWVhbl9wbG90KQ0KYGBgDQoNCg0KIyMjIEZpZ3VyZSBTOQ0KDQpNYWtpbmcgYSBPMmNyaXQgcGxvdCBmb3IgZWFjaCBvZiB0aGUgZWlnaHQgZmlzaCB0aGF0IHBhc3QgdmlzdWFsIGFuZCAgbnVtZXJpY2FsIGFzc2Vzc21lbnQgb24gdGhlIHNhbWUgYXhpcy4gICANCg0KYGBge3J9DQpwY3JpdF9zdW1tYXJ5IDwtIHBjcml0X21lYW5fcGxvdF9kZiAlPiUNCiAgZHBseXI6OmZpbHRlcihpZCAlaW4lIHNoYXJlZF9lbGVtZW50cykgJT4lIA0KICBncm91cF9ieShpZCkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBTTVIgPSBmaXJzdChTTVIpLA0KICAgIHBjcml0ID0gZmlyc3QocGNyaXQpLA0KICAgIG1heF9ETyA9IG1heChETywgbmEucm0gPSBUUlVFKSwNCiAgICBtZXRob2QgPSBmaXJzdChtZXRob2QpLA0KICAgIC5ncm91cHMgPSAiZHJvcCINCiAgKQ0KDQpzbW9vdGhfc2VnbWVudHMgPC0gbWFwX2Rmcih1bmlxdWUocGNyaXRfc3VtbWFyeSRpZCksIGZ1bmN0aW9uKGN1cl9pZCkgew0KICANCiAgc3VtX2luZm8gPC0gcGNyaXRfc3VtbWFyeSAlPiUgZmlsdGVyKGlkID09IGN1cl9pZCkNCiAgU01SX3ZhbCA8LSBzdW1faW5mbyRTTVINCiAgbWV0aG9kX3ZhbCA8LSBzdW1faW5mbyRtZXRob2QNCiAgDQogIGRmIDwtIHBjcml0X21lYW5fcGxvdF9kZiAlPiUNCiAgICBmaWx0ZXIoaWQgPT0gY3VyX2lkLCBsZWF0aGFsID09ICJub25yZWd1bGF0aW9uIikNCiAgDQogIGlmKG5yb3coZGYpIDwgMikgcmV0dXJuKE5VTEwpDQogIA0KICAjIEZpdCB0aGUgYXBwcm9wcmlhdGUgbW9kZWwNCiAgaWYobWV0aG9kX3ZhbCA9PSAidGhyb3VnaF9vcmlnaW4iKSB7DQogICAgbW9kZWwgPC0gbG0oTU8yIH4gRE8gKyAwLCBkYXRhID0gZGYpDQogIH0gZWxzZSB7DQogICAgbW9kZWwgPC0gbG0oTU8yIH4gRE8sIGRhdGEgPSBkZikNCiAgfQ0KICANCiAgY29lZnMgPC0gY29lZihtb2RlbCkNCiAgDQogIGlmKG1ldGhvZF92YWwgPT0gInRocm91Z2hfb3JpZ2luIikgew0KICAgIHNsb3BlIDwtIGNvZWZzWzFdDQogICAgRE9fc3RhcnQgPC0gMA0KICAgIERPX3N0b3AgPC0gU01SX3ZhbCAvIHNsb3BlDQogIH0gZWxzZSB7DQogICAgaW50ZXJjZXB0IDwtIGNvZWZzWzFdDQogICAgc2xvcGUgPC0gY29lZnNbMl0NCiAgICAjIEZvciBMU19yZWcsIHN0YXJ0IGF0IDAgaWYgcHJlZGljdGlvbiBpcyBhbHJlYWR5IHBvc2l0aXZlLA0KICAgICMgb3IgYXQgdGhlIERPIHdoZXJlIHByZWRpY3RlZCBNTzIgYmVjb21lcyAwIGlmIG5vdC4NCiAgICBET19zdGFydCA8LSBpZihpbnRlcmNlcHQgPCAwKSAtaW50ZXJjZXB0IC8gc2xvcGUgZWxzZSAwDQogICAgRE9fc3RvcCA8LSAoU01SX3ZhbCAtIGludGVyY2VwdCkgLyBzbG9wZQ0KICB9DQogIA0KICAjIElNUE9SVEFOVDogRG8gbm90IGJvdW5kIERPX3N0b3AgYnkgbWF4KGRmJERPKSBpZiB5b3Ugd2FudCB0byBleHRyYXBvbGF0ZQ0KICAjIERPX3N0b3AgPC0gbWluKERPX3N0b3AsIG1heChkZiRETywgbmEucm0gPSBUUlVFKSkgICMgPC0tIFJlbW92ZSBvciBjb21tZW50IG91dCB0aGlzIGxpbmUNCiAgDQogICMgQ3JlYXRlIGEgc2VxdWVuY2UgZnJvbSBET19zdGFydCB0byBET19zdG9wDQogIERPX3NlcSA8LSBzZXEoRE9fc3RhcnQsIERPX3N0b3AsIGxlbmd0aC5vdXQgPSAxMDApDQogIA0KICAjIENhbGN1bGF0ZSB0aGUgcHJlZGljdGVkIE1PMiB2YWx1ZXMgZm9yIHRoaXMgc2VxdWVuY2UNCiAgTU8yX3ByZWQgPC0gaWYobWV0aG9kX3ZhbCA9PSAidGhyb3VnaF9vcmlnaW4iKSB7DQogICAgc2xvcGUgKiBET19zZXENCiAgfSBlbHNlIHsNCiAgICBpbnRlcmNlcHQgKyBzbG9wZSAqIERPX3NlcQ0KICB9DQogIA0KICB0aWJibGUoDQogICAgaWQgPSBjdXJfaWQsDQogICAgRE8gPSBET19zZXEsDQogICAgTU8yX3ByZWQgPSBNTzJfcHJlZA0KICApIA0KICB9KQ0KDQpGaWdfczkgPC0gZ2dwbG90KCkgKw0KICBnZW9tX3BvaW50KGRhdGEgPSBwY3JpdF9tZWFuX3Bsb3RfZGYgJT4lDQogICAgICAgICAgICAgICBkcGx5cjo6ZmlsdGVyKGlkICVpbiUgc2hhcmVkX2VsZW1lbnRzKSwgDQogICAgICAgICAgICAgYWVzKHggPSBETywgeSA9IE1PMiwgY29sb3VyID0gaWQsIGFscGhhID0gbGVhdGhhbCkpICsNCiAgc2NhbGVfYWxwaGFfbWFudWFsKHZhbHVlcyA9IGMoInJlZ3VsYXRpb24iID0gMC4yLCAibm9ucmVndWxhdGlvbiIgPSAwLjgpKSArDQogIGd1aWRlcyhhbHBoYSA9ICJub25lIikgKw0KICBnZW9tX2xpbmUoZGF0YSA9IHNtb290aF9zZWdtZW50cywNCiAgICAgICAgICAgIGFlcyh4ID0gRE8sIHkgPSBNTzJfcHJlZCwgY29sb3VyID0gaWQpLCBsaW5ld2lkdGggPSAxLjIpICsNCiAgZ2VvbV9zZWdtZW50KGRhdGEgPSBwY3JpdF9zdW1tYXJ5LA0KICAgICAgICAgICAgIGFlcyh4ID0gcGNyaXQsIHhlbmQgPSBtYXhfRE8sIHkgPSBTTVIsIHllbmQgPSBTTVIpKSArDQogIGdlb21fc2VnbWVudChkYXRhID0gcGNyaXRfc3VtbWFyeSwNCiAgICAgICAgICAgICAgIGFlcyh4ID0gcGNyaXQsIHhlbmQgPSBwY3JpdCwgeSA9IDAsIHllbmQgPSBTTVIpKSArDQogIHNjYWxlX2NvbG91cl92aXJpZGlzX2Qob3B0aW9uID0gInBsYXNtYSIpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgbGFicygNCiAgICB5ID0gZXhwcmVzc2lvbigibWcgTyJbMl1+ImgiXi0xKSwNCiAgICB4ID0gIkRpc3NvbHZlZCBveHlnZW4gKERPOyAlIHNhdHVyYXRpb24pIg0KICApICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpDQoNCkZpZ19zOQ0KYGBgDQoNCg0KKipGaWd1cmUgUzkqKjogT3h5Z2VuIGNvbnN1bXB0aW9uIHJhdGUgKOG5gE/igoI7IG1n4oG7wrkgT+KCgiBo4oG7wrkpIGFuZCBhbWJpZW50IGRpc3NvbHZlZCBveHlnZW4gKERPOyAlIHNhdHVyYXRpb24pIHBsb3R0ZWQgZm9yIGVhY2ggZmlzaCB0aGF0IHBhc3NlZCBib3RoIHBhc3QgdmlzdWFsIGFuZCAgbnVtZXJpY2FsIGFzc2Vzc21lbnQgZm9yIE88c3ViPjJjcml0PC9zdWI+LiBUaGUgaG9yaXpvbnRhbCBkYXNoZWQgbGluZXMgc2hvdyBTTVIsIHRoZSBzb2xpZCBzbG9wZWQgbGluZXMgcmVwcmVzZW50IHRoZSBsaW5lYXIgYmVzdCBmaXQgZm9yIOG5gE8gdmFsdWVzIGJlbG93IHJlZ3VsYXRvcnkgZmFpbHVyZS4gVGhlIHZlcnRpY2FsIHNvaWxkIGxpbmVzIHJlcHJlc2VudCBPPHN1Yj4yY3JpdDwvc3ViPiAodGhlIGludGVyc2VjdGlvbiBvZiB0aGUgbGluZWFyIGJlc3QgZml0IGZvciDhuYBPIHZhbHVlcyBiZWxvdyByZWd1bGF0b3J5IGZhaWx1cmUgYW5kIFNNUikuDQoNCg0KDQojIyMgRmlndXJlIDINCg0KTGV0J3MgbWFrZSBzb21lIGV4YW1wbGUgcGxvdHMgZm9yIGVhY2ggbWFqb3IgdHlwZXMgb2YgTzItTU8yIHJlbGF0aW9uc2hpcHMgKGkuZS4gMF50aF4tLCAxXnN0Xi0sIGFuZCAyXm5kXi8zXnJkXi0gb3JkZXIgcG9seW5vbWlhbCkuICAgDQoNCkZpcnN0IGFuIGV4YW1wbGUgb2YgYSAwdGgtb3JkZXIgcG9seW5vbWlhbCBmaXQgKGNfOV8yNG5vdl80KS4gICANCg0KYGBge3J9DQpmaWdfMmEgPC0gYmF5ZXNfcmVnX21vZHNfcHJlZGljdGlvbnMgJT4lDQogIGRwbHlyOjpmaWx0ZXIoaWQgPT0gImNfOV8yNG5vdl80IiwgbW9kZWxfdHlwZSA9PSAibG1fMCIpICU+JSANCiAgZ2dwbG90KCkgKw0KICBnZW9tX3BvaW50KGFlcyh4ID0gRE8sIHkgPSBNTzIpLCBjb2xvdXIgPSAiYmxhY2siLCBzaXplID0gMywgYWxwaGEgPSAwLjUpICsNCiAgZ2VvbV9zZWdtZW50KA0KICAgIGFlcyh4ID0gMCwgeGVuZCA9IDEwMCwgeSA9IDAsIHllbmQgPSBTTVJbMV0pLCAjIFNNUg0KICAgIGxpbmV0eXBlID0gImRhc2hlZCIsIHNpemUgPSAxLCBjb2xvdXIgPSAiIzBGN0FBRiIpICsNCiAgZ2VvbV9zZWdtZW50KA0KICAgIGFlcyh4ID0gMCwgeGVuZCA9IDEwMCwgeSA9IFNNUlsxXSwgeWVuZCA9IFNNUlsxXSksICMgY29uZm9ybQ0KICAgIGxpbmV0eXBlID0gImRhc2hlZCIsIHNpemUgPSAxLCBjb2xvdXIgPSAiI0ZGQTUwMCIpICsNCiAgdGhlbWVfZmV3KCkgKw0KICAgIGxhYnMoDQogICAgeSA9IGV4cHJlc3Npb24oIm1nIE8iWzJdfiJoIl4tMSksDQogICAgeCA9IE5VTEwNCiAgKSArDQogIHRoZW1lKA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCkNCiAgKQ0KYGBgDQoNCg0KU2Vjb25kIGFuIGV4YW1wbGUgb2YgYSAxc3Qtb3JkZXIgcG9seW5vbWlhbCBiZXN0IGZpdCAoZF85XzI1bm92XzMpLiAgDQoNCmBgYHtyfQ0KZmlnXzJiIDwtIGJheWVzX3JlZ19tb2RzX3ByZWRpY3Rpb25zICU+JQ0KICBkcGx5cjo6ZmlsdGVyKGlkID09ICJkXzlfMjVub3ZfMyIsIG1vZGVsX3R5cGUgPT0gImxtXzEiKSAlPiUgDQogIGdncGxvdCgpICsNCiAgZ2VvbV9wb2ludChhZXMoeCA9IERPLCB5ID0gTU8yKSwgY29sb3VyID0gImJsYWNrIiwgc2l6ZSA9IDMsIGFscGhhID0gMC41KSArDQogICMgZ2VvbV9saW5lKGFlcyh4ID0gRE8sIHkgPSBwcmVkaWN0ZWQgKiBtYXNzKSwgc2l6ZSA9IDIsIGNvbG91ciA9ICJibHVlIikgKw0KICBnZW9tX3NlZ21lbnQoDQogICAgYWVzKHggPSAwLCB4ZW5kID0gMTAwLCB5ID0gMCwgeWVuZCA9IFNNUlsxXSksICMgU01SDQogICAgbGluZXR5cGUgPSAiZGFzaGVkIiwgc2l6ZSA9IDEsIGNvbG91ciA9ICIjMEY3QUFGIikgKw0KICBnZW9tX3NlZ21lbnQoDQogICAgYWVzKHggPSAwLCB4ZW5kID0gMTAwLCB5ID0gU01SWzFdLCB5ZW5kID0gU01SWzFdKSwgIyBjb25mb3JtDQogICAgbGluZXR5cGUgPSAiZGFzaGVkIiwgc2l6ZSA9IDEsIGNvbG91ciA9ICIjRkZBNTAwIikgKw0KICB0aGVtZV9mZXcoKSArDQogIGxhYnMoDQogICAgeSA9IGV4cHJlc3Npb24oIm1nIE8iWzJdfiJoIl4tMSksDQogICAgeCA9IE5VTEwNCiAgKSArDQogIHRoZW1lKA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKQ0KICApDQoNCmBgYA0KDQoNCkxhc3QgYW4gZXhhbXBsZSBvZiBhIGZpc2ggYmVzdCBmaXQgd2l0aCBhIGhpZ2hlciBvcmRlciBwb2x5bm9taWFsICgybmQtb3JkZXIpLg0KDQpgYGB7cn0NCiMgRGVmaW5lIHRoZSBleGFtcGxlIElEDQpwY3JpdF9leGFtcGxlIDwtICJiXzBfMjRub3ZfMSINCg0KIyAxLiBQcmVwYXJlIHN1bW1hcnkgZGF0YSBmb3IgdGhlIHNlbGVjdGVkIElEDQpwY3JpdF9zdW1tYXJ5X2V4YW1wbGUgPC0gcGNyaXRfbWVhbl9wbG90X2RmICU+JQ0KICBmaWx0ZXIoaWQgPT0gcGNyaXRfZXhhbXBsZSkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBTTVIgPSBmaXJzdChTTVIpLA0KICAgIHBjcml0ID0gZmlyc3QocGNyaXQpLA0KICAgIG1heF9ETyA9IG1heChETywgbmEucm0gPSBUUlVFKSwNCiAgICBtZXRob2QgPSBmaXJzdChtZXRob2QpLA0KICAgIC5ncm91cHMgPSAiZHJvcCINCiAgKQ0KDQojIDIuIFN1YnNldCB0aGUgb3JpZ2luYWwgbm9ucmVndWxhdGlvbiBkYXRhDQpkZiA8LSBwY3JpdF9tZWFuX3Bsb3RfZGYgJT4lDQogIGZpbHRlcihpZCA9PSBwY3JpdF9leGFtcGxlLCBsZWF0aGFsID09ICJub25yZWd1bGF0aW9uIikNCg0KIyAzLiBGaXQgbW9kZWwgYW5kIGdlbmVyYXRlIHByZWRpY3Rpb25zDQppZiAobnJvdyhkZikgPj0gMikgew0KICBTTVJfdmFsIDwtIHBjcml0X3N1bW1hcnlfZXhhbXBsZSRTTVINCiAgbWV0aG9kX3ZhbCA8LSBwY3JpdF9zdW1tYXJ5X2V4YW1wbGUkbWV0aG9kDQogIA0KICBpZiAobWV0aG9kX3ZhbCA9PSAidGhyb3VnaF9vcmlnaW4iKSB7DQogICAgbW9kZWwgPC0gbG0oTU8yIH4gRE8gKyAwLCBkYXRhID0gZGYpDQogICAgc2xvcGUgPC0gY29lZihtb2RlbClbMV0NCiAgICBET19zdGFydCA8LSAwDQogICAgRE9fc3RvcCA8LSBTTVJfdmFsIC8gc2xvcGUNCiAgICBNTzJfcHJlZCA8LSBzbG9wZSAqIHNlcShET19zdGFydCwgRE9fc3RvcCwgbGVuZ3RoLm91dCA9IDEwMCkNCiAgfSBlbHNlIHsNCiAgICBtb2RlbCA8LSBsbShNTzIgfiBETywgZGF0YSA9IGRmKQ0KICAgIGludGVyY2VwdCA8LSBjb2VmKG1vZGVsKVsxXQ0KICAgIHNsb3BlIDwtIGNvZWYobW9kZWwpWzJdDQogICAgRE9fc3RhcnQgPC0gaWYgKGludGVyY2VwdCA8IDApIC1pbnRlcmNlcHQgLyBzbG9wZSBlbHNlIDANCiAgICBET19zdG9wIDwtIChTTVJfdmFsIC0gaW50ZXJjZXB0KSAvIHNsb3BlDQogICAgRE9fc2VxIDwtIHNlcShET19zdGFydCwgRE9fc3RvcCwgbGVuZ3RoLm91dCA9IDEwMCkNCiAgICBNTzJfcHJlZCA8LSBpbnRlcmNlcHQgKyBzbG9wZSAqIERPX3NlcQ0KICB9DQogIA0KICBET19zZXEgPC0gc2VxKERPX3N0YXJ0LCBET19zdG9wLCBsZW5ndGgub3V0ID0gMTAwKQ0KICANCiAgc21vb3RoX3NlZ21lbnQgPC0gdGliYmxlKA0KICAgIGlkID0gcGNyaXRfZXhhbXBsZSwNCiAgICBETyA9IERPX3NlcSwNCiAgICBNTzJfcHJlZCA9IE1PMl9wcmVkDQogICkNCn0NCg0KIyA0LiBQbG90IHRoZSBmaWd1cmUNCmZpZ18yYyA8LSBnZ3Bsb3QoKSArDQogIGdlb21fcG9pbnQoDQogICAgZGF0YSA9IHBjcml0X21lYW5fcGxvdF9kZiAlPiUgZmlsdGVyKGlkID09IHBjcml0X2V4YW1wbGUpLA0KICAgIGFlcyh4ID0gRE8sIHkgPSBNTzIsIGNvbG91ciA9IGxlYXRoYWwpLCBzaXplID0gMywgYWxwaGEgPSAwLjUNCiAgKSArDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygicmVndWxhdGlvbiIgPSAiYmxhY2siLCAibm9ucmVndWxhdGlvbiIgPSAiI2MzMDAxMCIpKSArDQogIA0KICAjIGdlb21fc21vb3RoKGRhdGEgPSBwY3JpdF9tZWFuX3Bsb3RfZGYgJT4lIGZpbHRlcihpZCA9PSBwY3JpdF9leGFtcGxlKSwNCiAgIyAgICAgICAgICAgICBhZXMoeCA9IERPLCB5ID0gTU8yKSwgbWV0aG9kID0gImxtIiwgZm9ybXVsYSA9IHkgfiBwb2x5KHgsIDMpLCBzZSA9IEZBTFNFLCBhbHBoYSA9IDAuOCwgc2l6ZSA9IDIsIGZ1bGxyYW5nZSA9IFRSVUUpICsNCiAgDQogIGdlb21fbGluZSgNCiAgICBkYXRhID0gc21vb3RoX3NlZ21lbnQsDQogICAgYWVzKHggPSBETywgeSA9IE1PMl9wcmVkKSwgc2l6ZSA9IDIsIGNvbG91ciA9ICIjYzMwMDEwIiAjZmFpbHVyZSAgc2xvcGUNCiAgKSArDQogIA0KICANCiAgZ2VvbV9zZWdtZW50KA0KICAgIGRhdGEgPSBwY3JpdF9zdW1tYXJ5X2V4YW1wbGUsDQogICAgYWVzKHggPSAwLCB4ZW5kID0gbWF4X0RPLCB5ID0gU01SLCB5ZW5kID0gU01SKSwgI1NNUg0KICAgIGNvbG91ciA9ICIjRkZBNTAwIiwgbGluZXR5cGUgPSAiZGFzaGVkIiwgc2l6ZSA9IDEpICsNCiAgDQogIGdlb21fc2VnbWVudCgNCiAgICBkYXRhID0gcGNyaXRfc3VtbWFyeV9leGFtcGxlLA0KICAgIGFlcyh4ID0gMCwgeGVuZCA9IG1heF9ETywgeSA9IDAsIHllbmQgPSBTTVIpLCAjY29uZnJvbQ0KICAgIGxpbmV0eXBlID0gImRhc2hlZCIsIHNpemUgPSAxLCBjb2xvdXIgPSAiIzBGN0FBRiIpICsNCiAgDQogIGdlb21fc2VnbWVudCgNCiAgICBkYXRhID0gcGNyaXRfc3VtbWFyeV9leGFtcGxlLA0KICAgIGFlcyh4ID0gcGNyaXQsIHhlbmQgPSBwY3JpdCwgeSA9IDAsIHllbmQgPSBTTVIpLCBjb2xvdXIgPSAiZGFya2dyZWVuIiwgc2l6ZSA9IDIgI1Bjcml0DQogICkgKw0KICANCiAgI2Nvb3JkX2NhcnRlc2lhbih5bGltID0gYygwLCAwLjE2KSkgKw0KICB0aGVtZV9mZXcoKSArDQogICBsYWJzKA0KICAgIHkgPSBleHByZXNzaW9uKCJtZyBPIlsyXX4iaCJeLTEpLA0KICAgIHggPSAiRGlzc29sdmVkIG94eWdlbiAoRE87ICUgc2F0dXJhdGlvbikiDQogICkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQoNCmBgYA0KDQoNCkxldCdzIGNvbWJpbmVkIHRoZW0gaW4gb25lIHBsb3QNCg0KYGBge3IsIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD01fQ0KZmlnXzJfYmluZCA8LSBncmlkLmFycmFuZ2UoZmlnXzJhLCBmaWdfMmIsIGZpZ18yYywgbmNvbCA9IDEpICNiaW5kIHBsb3QNCmBgYA0KDQoqKkZpZ3VyZSAyKio6IEZpZ3VyZSAyLiBSZXByZXNlbnRhdGl2ZSBleGFtcGxlcyBvZiBmaXNoIHRoYXQgd2VyZSBiZXN0IG1vZGVsbGVkIGJ5IGEgMHRoLW9yZGVyIHBvbHlub21pYWwgKEEpLCAxc3Qtb3JkZXIgcG9seW5vbWlhbCAoQiksIGFuZCAybmQtb3JkZXIgcG9seW5vbWlhbCAoQykuIFRoZSBvcmFuZ2UgZGFzaGVkIGxpbmUgc2hvd3MgdGhlIFNNUiwgd2hpbGUgdGhlIGJsdWUgZGFzaGVkIGxpbmUgc2hvd3MgdGhlIHRoZW9yZXRpY2FsIG94eWNvbmZyb21pbmcgcmVncmVzc2lvbi4gRm9yIHBsb3QgKEMpLCB0aGUgcmVkIHNsb3BlZCBsaW5lIHNob3dzIHRoZSBPMiByZWd1bGF0aW9uIGZhaWx1cmUgcmVncmVzc2lvbiAoYmFzZWQgb24gdGhlIHJ1bGUtYmFzZWQgbGluZWFyIHJlZ3Jlc3Npb24gbWV0aG9kIG9mIENsYWlyZWF1eCBhbmQgQ2hhYm90LCAyMDE2KSwgYW5kIHRoZSBzb2xpZCBob3Jpem9udGFsIGdyZWVuIGxpbmUgc2hvd3MgdGhlIE8yY3JpdCBlc3RpbWF0ZSAoaW50ZXJzZWN0aW9uIG9mIE8yIGZhaWx1cmUgcmVncmVzc2lvbiBhbmQgU01SKS4gIA0KDQpgYGB7cn0NCiMgZ2dzYXZlKGZpbGVuYW1lID0gcGFzdGUwKG91dHB1dF9maWdfd2QsICIuL21zX2ZpZ3VyZXMuL2ZpZ3VyZS0yLnBkZiIpLA0KIyAgICAgICAgcGxvdCA9IGZpZ18yX2JpbmQsDQojICAgICAgICB3aWR0aCA9IDIxMCwNCiMgICAgICAgIGhlaWdodCA9IDI5NywNCiMgICAgICAgIHVuaXRzID0gIm1tIikNCmBgYA0KDQoNCiMgQ29tYXByaW5nIHRvIHBhc3QgZGF0YQ0KDQpIZXJlLCB3ZSBoYXZlIHJlY3JlYXRlZCBhIHNpbWlsYXIgcGxvdCB0byB0aGF0IHByZXNlbnRlZCBpbiBVcmJpbmEsIEdsb3ZlciwgYW5kIEZvcnN0ZXIgKDIwMTIpXlsxXV4gYW5kIGhhdmUgZXh0cmFjdGVkIHRoZSBtZWFuIGxldmVsIGRhdGEgZnJvbSBGaWd1cmUgMWEgdXNpbmcgdGhlIG1ldGFEaWdpdGlzZSBwYWNrYWdlIGluIFJeWzNdXi4gVGhpcyBkYXRhIGlzIGNhbGxlZCB1cmJpbmFfZXRfYWxfMjAxMi4gVGhpcyBhbGxvd3MgdXMgdG8gY29tcGFyZSB0aGUgZGlmZmVyZW5jZXMgaW4gTW8yIGFuZCB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gTW8yIGFuZCBPPHN1Yj4yPC9zdWI+Lg0KDQpGaXJzdCBtYWtpbmcgYSBiaW5uZWQgZGF0YSBmcmFtZSB0byBtYXRjaCBVcmJpbmEsIEdsb3ZlciwgYW5kIEZvcnN0ZXIgKDIwMTIpIGFzIGNsb3NlbHkgYXMgcG9zc2libGUuDQoNCmBgYHtyfQ0KbWluX28yX2twYSA8LSBtaW4oc2xvcGVfdGlkeSRvMl9rcGEsIG5hLnJtID0gVFJVRSkNCm1heF9vMl9rcGEgPC0gbWF4KHNsb3BlX3RpZHkkbzJfa3BhLCBuYS5ybSA9IFRSVUUpDQoNCnRpbWVfYmluX2RmIDwtIHNsb3BlX3RpZHkgJT4lDQogIG11dGF0ZShvMl9ncm91cCA9IGN1dChvMl9rcGEsIA0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gc2VxKG1pbl9vMl9rcGEsIG1heF9vMl9rcGEsIGxlbmd0aC5vdXQgPSAxMyksICMgMTEgaW50ZXJ2YWxzLCBzbyAxMiBicmVha3BvaW50cw0KICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gcGFzdGUwKCJHcm91cCAiLCAxOjEyKSwgDQogICAgICAgICAgICAgICAgICAgICAgICBpbmNsdWRlLmxvd2VzdCA9IFRSVUUpKSAlPiUgDQogIGRwbHlyOjpncm91cF9ieShvMl9ncm91cCkgJT4lIA0KICBkcGx5cjo6cmVmcmFtZShtZWFuX01PMl9nID0gbWVhbihNTzJfZykqMzEuMjUsDQogICAgICAgICAgICAgICAgIG1lYW5fbzJfa3BhID0gbWVhbihvMl9rcGEpLA0KICAgICAgICAgICAgICAgICBuID0gbGVuZ3RoKE1PMl9nKSozMS4yNSwNCiAgICAgICAgICAgICAgICAgTU8yX2dfc2QgPSBzZChNTzJfZykqMzEuMjUsDQogICAgICAgICAgICAgICAgIG8yX2twYV9zZCA9IHNkKG8yX2twYSkpDQpgYGANCg0KIyMgRmlndXJlIDMNCg0KTm93IHRoZSBwbG90IHdpdGggb3VyIG1lYW4gZGF0YSBhbmQgdGhlIG1lYW4gZGF0YSBmcm9tIFVyYmluYSwgR2xvdmVyLCBhbmQgRm9yc3RlciAoMjAxMileWzFdXiAgIA0KDQpgYGB7cn0NCm4gPC0gc2xvcGVfdGlkeSAlPiUgDQogIGRwbHlyOjpkaXN0aW5jdChpZCkgJT4lIA0KICBucm93KC4pDQoNCiMgRXhpc3RpbmcgcGxvdA0KZmlnMyA8LSB0aW1lX2Jpbl9kZiAlPiUgDQogIGdncGxvdCgpICsNCiAgZ2VvbV9wb2ludChkYXRhID0gc2xvcGVfdGlkeSwgDQogICAgICAgICAgICAgYWVzKHkgPSBNTzJfZyAqIDMxLjI1LCB4ID0gbzJfa3BhKSwgDQogICAgICAgICAgICAgc2l6ZSA9IDIsIGNvbG9yID0gImdyZXkiLCBhbHBoYSA9IDAuMykgKyAgDQogIGdlb21fcG9pbnQoZGF0YSA9IHRpbWVfYmluX2RmLCANCiAgICAgICAgICAgICBhZXMoeSA9IG1lYW5fTU8yX2csIHggPSBtZWFuX28yX2twYSksDQogICAgICAgICAgICAgc2l6ZSA9IDMsIGNvbG91ciA9ICIjMEU0QzkyIiwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKw0KICBnZW9tX2Vycm9yYmFyKGRhdGEgPSB0aW1lX2Jpbl9kZiwNCiAgICAgICAgICAgICAgICBhZXMoeSA9IG1lYW5fTU8yX2csIHggPSBtZWFuX28yX2twYSwNCiAgICAgICAgICAgICAgICAgICAgeW1pbiA9IG1lYW5fTU8yX2cgLSBNTzJfZ19zZCwgeW1heCA9IG1lYW5fTU8yX2cgKyBNTzJfZ19zZCksIA0KICAgICAgICAgICAgICAgIHdpZHRoID0gMC4xNSwgY29sb3VyID0gIiMwRTRDOTIiKSArDQogIGdlb21fZXJyb3JiYXJoKGRhdGEgPSB0aW1lX2Jpbl9kZiwgDQogICAgICAgICAgICAgICAgIGFlcyh5ID0gbWVhbl9NTzJfZywgeCA9IG1lYW5fbzJfa3BhLA0KICAgICAgICAgICAgICAgICAgICAgeG1pbiA9IG1lYW5fbzJfa3BhIC0gbzJfa3BhX3NkLCB4bWF4ID0gbWVhbl9vMl9rcGEgKyBvMl9rcGFfc2QpLCANCiAgICAgICAgICAgICAgICAgaGVpZ2h0ID0gMC40LCBjb2xvdXIgPSAiIzBFNEM5MiIpICsNCiAgZ2VvbV9wb2ludChkYXRhID0gdXJiaW5hX2V0X2FsXzIwMTIsIA0KICAgICAgICAgICAgIGFlcyh4ID0gbzJfbWVhbiwgeSA9IG1vMl9tZWFuKSwgDQogICAgICAgICAgICAgc2l6ZSA9IDMsIHNoYXBlID0gMSwgZmlsbCA9ICIjRDIxRjNDIiwgY29sb3IgPSAiI0QyMUYzQyIsIHN0cm9rZSA9IDEpICsNCiAgZ2VvbV9lcnJvcmJhcihkYXRhID0gdXJiaW5hX2V0X2FsXzIwMTIsIA0KICAgICAgICAgICAgICAgIGFlcyh4ID0gbzJfbWVhbiwgeW1pbiA9IG1vMl9tZWFuIC0gbW8yX3NkLCB5bWF4ID0gbW8yX21lYW4gKyBtbzJfc2QpLCANCiAgICAgICAgICAgICAgICB3aWR0aCA9IDAuMiwgY29sb3VyID0gIiNEMjFGM0MiKSArDQogIGdlb21fZXJyb3JiYXJoKGRhdGEgPSB1cmJpbmFfZXRfYWxfMjAxMiwgDQogICAgICAgICAgICAgICAgIGFlcyh5ID0gbW8yX21lYW4sIHhtaW4gPSBvMl9tZWFuIC0gbzJfc2QsIHhtYXggPSBvMl9tZWFuICsgbzJfc2QpLCANCiAgICAgICAgICAgICAgICAgaGVpZ2h0ID0gMC40LCBjb2xvdXIgPSAiI0QyMUYzQyIpICsNCiAgYW5ub3RhdGUoInRleHQiLCB4ID0gMCwgDQogICAgICAgICAgIHkgPSAxNiwgDQogICAgICAgICAgIGxhYmVsID0gYnF1b3RlKGF0b3AoIkN1cnJlbnQgZGF0YSAoYmx1ZSksICIgKiBpdGFsaWMobikgKiAiID0gIiAqIC4obiksDQogICAgICAgICAgICAgICAgICAgICAgICAiVXJiaW5hIGRhdGEgKHJlZCksICIgKiBpdGFsaWMobikgKiAiID0gNjciKSksICANCiAgICAgICAgIGhqdXN0ID0gMCwgdmp1c3QgPSAxLCBzaXplID0gNCkgKw0KICB0aGVtZSgNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiYmxhY2siLCBmaWxsID0gTkEsIGxpbmV3aWR0aCA9IDEpLA0KICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIsIGNvbG91ciA9IE5BKSwNCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIsIGNvbG91ciA9IE5BKQ0KICApICsNCiAgbGFicygNCiAgc3VidGl0bGUgPSBOVUxMLA0KICB4ID0gZXhwcmVzc2lvbigiUE8iWzJdfiIoa1BhKSIpLA0KICB5ID0gZXhwcmVzc2lvbigiTU8iWzJdfiIozrxtb2wgTyJbMl1+ImciXi0xfiJoIl4tMSkpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMTYpLCBicmVha3MgPSBzZXEoMCwgMTYsIGJ5ID0gMikpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMjIpLCBicmVha3MgPSBzZXEoMCwgMjIsIGJ5ID0gMikpICANCg0KZmlnMw0KYGBgDQoNCioqRmlndXJlIDM6KiogTWVhbiBhbmQgc3RhbmRhcmQgZXJyb3Igb2YgbWV0YWJvbGljIHJhdGUgKE1PPHN1Yj4yPC9zdWI+IM68bW9sIE88c3ViPjI8L3N1Yj4gZ14tMV4gaF4tMV4pIGFuZCBveHlnZW4gY29uY2VudHJhdGlvbiAoUE88c3ViPjI8L3N1Yj4ga1BhKSB1c2luZyAxMiBldmVubHkgc3BhY2VkIGJpbnMgb3ZlciB0aGUgTzxzdWI+Mjwvc3ViPiByYW5nZSBvZiBvYnNlcnZlZCBkYXRhIChibHVlIGZpbGxlZCBkb3RzKS4gQ29tcGFyZWQgYWdhaW5zdCB0aGUgbWVhbiBhbmQgc3RhbmRhcmQgZXJyb3IgcmVwb3J0ZWQgaW4gVXJiaW5hICgyMDEyKV5bMV1eIChyZWQgb3BlbiBkb3RzKS4gVGhlIGdyZXkgZG90cyBhcmUgdGhlIHJhdyBvYnNlcnZlZCBkYXRhIGZvcm0gdGhlIHByZXNlbnQgc3R1ZHkuDQoNCmBgYHtyfQ0KIyBnZ3NhdmUoZmlsZW5hbWUgPSBwYXN0ZTAob3V0cHV0X2ZpZ193ZCwgIi4vbXNfZmlndXJlcy4vZmlndXJlLTMucGRmIiksDQojICAgICAgICBwbG90ID0gZmlnMywNCiMgICAgICAgIHdpZHRoID0gMjEwLA0KIyAgICAgICAgaGVpZ2h0ID0gMjk3LzIsICAjIFNwZWNpZnkgdGhlIGhlaWdodCBvZiB0aGUgcGxvdA0KIyAgICAgICAgdW5pdHMgPSAibW0iKQ0KYGBgDQoNCjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT4NCg0KIyDwn5OaIFJlZmVyZW5jZXMNCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQpeWzFdXiBDbGFpcmVhdXgsIEcuIGFuZCBDaGFib3QsIEQuICgyMDE2KSBSZXNwb25zZXMgYnkgZmlzaGVzIHRvIGVudmlyb25tZW50YWwgaHlwb3hpYTogaW50ZWdyYXRpb24gdGhyb3VnaCBGcnkncyBjb25jZXB0IG9mIGFlcm9iaWMgbWV0YWJvbGljIHNjb3BlLiBKb3VybmFsIG9mIEZpc2ggQmlvbG9neSA8aHR0cHM6Ly9kb2kub3JnLzEwLjExMTEvamZiLjEyODMzPg0KDQpeWzJdXiBVcmJpbmEgTUEsIEdsb3ZlciBDTiwgYW5kIEZvcnN0ZXIgTUUsICgyMDEyKSBBIG5vdmVsIG94eWNvbmZvcm1pbmcgcmVzcG9uc2UgaW4gdGhlIGZyZXNod2F0ZXIgZmlzaCAqR2FsYXhpYXMgbWFjdWxhdHVzKi4gQ29tcGFyYXRpdmUgQmlvY2hlbWlzdHJ5IGFuZCBQaHlzaW9sb2d5IFBhcnQgQTogTW9sZWN1bGFyICYgSW50ZWdyYXRpdmUgUGh5c2lvbG9neS4gPGh0dHBzOi8vZG9pLm9yZy8xMC4xMDE2L2ouY2JwYS4yMDExLjExLjAxMT4NCg0KXlszXV4gUGljayBKTCwgTmFrYWdhd2EgUywgYW5kIE5vYmxlIERXQSAoMjAxOCkgUmVwcm9kdWNpYmxlLCBmbGV4aWJsZSBhbmQgaGlnaC10aHJvdWdocHV0IGRhdGEgZXh0cmFjdGlvbiBmcm9tIHByaW1hcnkgbGl0ZXJhdHVyZTogVGhlIG1ldGFEaWdpdGlzZSByIHBhY2thZ2UuIDxodHRwczovL2RvaS5vcmcvMTAuMTExMS8yMDQxLTIxMFguMTMxMTg+DQoNCjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT4NCg0KIyDwn5K7IFNlc3Npb24gaW5mb3JtYXRpb24NCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQpgYGB7cn0NCmNpdGF0aW9uKCkNCmBgYA0KDQpIZXJlIGlzIGEgZGV0YWlsZWQgbGlzdCBvZiB0aGUgc2Vzc2lvbiBpbmZvcm1hdGlvbg0KDQpgYGB7cn0NCnNlc3Npb25pbmZvOjpzZXNzaW9uX2luZm8oKQ0KYGBgDQo=